Fix bugs
[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)     free(config_info->engine_id);
441                 if (NULL != config_info->setting)       free(config_info->setting);
442                 if (NULL != config_info->language)      free(config_info->language);
443
444                 free(config_info);
445         }
446
447         return 0;
448 }
449
450 int stt_parser_set_engine(const char* engine_id, const char* setting, const char* language, bool silence, bool credential)
451 {
452         if (NULL == g_config_doc || NULL == engine_id)
453                 return -1;
454
455         xmlNodePtr cur = NULL;
456         cur = xmlDocGetRootElement(g_config_doc);
457         if (cur == NULL) {
458                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
459                 return -1;
460         }
461
462         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
463                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
464                 return -1;
465         }
466
467         cur = cur->xmlChildrenNode;
468         if (cur == NULL) {
469                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
470                 return -1;
471         }
472
473         while (cur != NULL) {
474                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_ID)) {
475                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
476                 }
477
478                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
479                         xmlNodeSetContent(cur, (const xmlChar *)language);
480                 }
481
482                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_SETTING)) {
483                         xmlNodeSetContent(cur, (const xmlChar *)setting);
484                 }
485
486                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
487                         if (true == silence)
488                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
489                         else
490                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
491                 }
492
493                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_CREDENTIAL)) {
494                         if (true == credential)
495                                 xmlNodeSetContent(cur, (const xmlChar *)"true");
496                         else
497                                 xmlNodeSetContent(cur, (const xmlChar *)"false");
498                 }
499
500                 cur = cur->next;
501         }
502
503         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
504         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
505
506         return 0;
507 }
508
509 int stt_parser_set_language(const char* language)
510 {
511         if (NULL == g_config_doc || NULL == language)
512                 return -1;
513
514         xmlNodePtr cur = NULL;
515         cur = xmlDocGetRootElement(g_config_doc);
516         if (cur == NULL) {
517                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
518                 return -1;
519         }
520
521         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
522                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
523                 return -1;
524         }
525
526         cur = cur->xmlChildrenNode;
527         if (cur == NULL) {
528                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
529                 return -1;
530         }
531
532         while (cur != NULL) {
533                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
534                         xmlNodeSetContent(cur, (const xmlChar *)language);
535                 }
536
537                 cur = cur->next;
538         }
539
540         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
541         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
542
543
544         return 0;
545 }
546
547 int stt_parser_set_auto_lang(bool value)
548 {
549         if (NULL == g_config_doc)
550                 return -1;
551
552         xmlNodePtr cur = NULL;
553         cur = xmlDocGetRootElement(g_config_doc);
554         if (cur == NULL) {
555                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
556                 return -1;
557         }
558
559         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
560                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
561                 return -1;
562         }
563
564         cur = cur->xmlChildrenNode;
565         if (cur == NULL) {
566                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
567                 return -1;
568         }
569
570         while (cur != NULL) {
571                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
572                         if (true == value) {
573                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
574                         } else if (false == value) {
575                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
576                         } else {
577                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong value of auto voice");
578                                 return -1;
579                         }
580                         break;
581                 }
582                 cur = cur->next;
583         }
584
585         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
586         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
587
588         return 0;
589 }
590
591 int stt_parser_set_silence_detection(bool value)
592 {
593         if (NULL == g_config_doc)
594                 return -1;
595
596         xmlNodePtr cur = NULL;
597         cur = xmlDocGetRootElement(g_config_doc);
598         if (cur == NULL) {
599                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
600                 return -1;
601         }
602
603         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
604                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
605                 return -1;
606         }
607
608         cur = cur->xmlChildrenNode;
609         if (cur == NULL) {
610                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
611                 return -1;
612         }
613
614         while (cur != NULL) {
615                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
616                         if (true == value)
617                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
618                         else
619                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
620                 }
621
622                 cur = cur->next;
623         }
624
625         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
626         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
627
628         return 0;
629 }
630
631 int stt_parser_find_config_changed(char** engine, char** setting, int* auto_lang, char** language, int* silence, int* credential)
632 {
633         if (NULL == engine || NULL == language || NULL == silence || NULL == credential) {
634                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
635                 return -1;
636         }
637
638         xmlDocPtr doc = NULL;
639         xmlNodePtr cur_new = NULL;
640         xmlNodePtr cur_old = NULL;
641
642         xmlChar *key_new;
643         xmlChar *key_old;
644
645         doc = xmlParseFile(STT_CONFIG);
646         if (doc == NULL) {
647                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_CONFIG);
648                 return -1;
649         }
650
651         cur_new = xmlDocGetRootElement(doc);
652         cur_old = xmlDocGetRootElement(g_config_doc);
653         if (cur_new == NULL || cur_old == NULL) {
654                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
655                 xmlFreeDoc(doc);
656                 return -1;
657         }
658
659         if (xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_BASE_TAG) || xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_BASE_TAG)) {
660                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
661                 xmlFreeDoc(doc);
662                 return -1;
663         }
664
665         cur_new = cur_new->xmlChildrenNode;
666         cur_old = cur_old->xmlChildrenNode;
667         if (cur_new == NULL || cur_old == NULL) {
668                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
669                 xmlFreeDoc(doc);
670                 return -1;
671         }
672
673         *engine = NULL;
674         *setting = NULL;
675         *language = NULL;
676
677         while (cur_new != NULL && cur_old != NULL) {
678                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_ID)) {
679                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_ID)) {
680                                 key_old = xmlNodeGetContent(cur_old);
681                                 if (NULL != key_old) {
682                                         key_new = xmlNodeGetContent(cur_new);
683                                         if (NULL != key_new) {
684                                                 if (0 != xmlStrcmp(key_old, key_new)) {
685                                                         SLOG(LOG_DEBUG, stt_tag(), "Old engine id(%s), New engine(%s)", (char*)key_old, (char*)key_new);
686                                                         if (NULL != *engine)    free(*engine);
687                                                         *engine = strdup((char*)key_new);
688                                                 }
689                                                 xmlFree(key_new);
690                                         }
691                                         xmlFree(key_old);
692                                 }
693                         } else {
694                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Old config and new config are different");
695                         }
696                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_SETTING)) {
697                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_SETTING)) {
698                                 key_old = xmlNodeGetContent(cur_old);
699                                 if (NULL != key_old) {
700                                         key_new = xmlNodeGetContent(cur_new);
701                                         if (NULL != key_new) {
702                                                 if (0 != xmlStrcmp(key_old, key_new)) {
703                                                         SLOG(LOG_DEBUG, stt_tag(), "Old engine setting(%s), New engine setting(%s)", (char*)key_old, (char*)key_new);
704                                                         if (NULL != *setting)   free(*setting);
705                                                         *setting = strdup((char*)key_new);
706                                                 }
707                                                 xmlFree(key_new);
708                                         }
709                                         xmlFree(key_old);
710                                 }
711                         } else {
712                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Old config and new config are different");
713                         }
714                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
715                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
716                                 key_old = xmlNodeGetContent(cur_old);
717                                 if (NULL != key_old) {
718                                         key_new = xmlNodeGetContent(cur_new);
719                                         if (NULL != key_new) {
720                                                 if (0 != xmlStrcmp(key_old, key_new)) {
721                                                         SLOG(LOG_DEBUG, stt_tag(), "Old auto lang(%s), New auto lang(%s)", (char*)key_old, (char*)key_new);
722                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
723                                                                 *auto_lang = (int)true;
724                                                         } else {
725                                                                 *auto_lang = (int)false;
726                                                         }
727                                                 }
728
729                                                 xmlFree(key_new);
730                                         }
731                                         xmlFree(key_old);
732                                 }
733                         } else {
734                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
735                         }
736                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_LANGUAGE)) {
737                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_LANGUAGE)) {
738                                 key_old = xmlNodeGetContent(cur_old);
739                                 if (NULL != key_old) {
740                                         key_new = xmlNodeGetContent(cur_new);
741                                         if (NULL != key_new) {
742                                                 if (0 != xmlStrcmp(key_old, key_new)) {
743                                                         SLOG(LOG_DEBUG, stt_tag(), "Old language(%s), New language(%s)", (char*)key_old, (char*)key_new);
744                                                         if (NULL != *language)  free(*language);
745                                                         *language = strdup((char*)key_new);
746                                                 }
747                                                 xmlFree(key_new);
748                                         }
749                                         xmlFree(key_old);
750                                 }
751                         } else {
752                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
753                         }
754                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_SILENCE_DETECTION)) {
755                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_SILENCE_DETECTION)) {
756                                 key_old = xmlNodeGetContent(cur_old);
757                                 if (NULL != key_old) {
758                                         key_new = xmlNodeGetContent(cur_new);
759                                         if (NULL != key_new) {
760                                                 if (0 != xmlStrcmp(key_old, key_new)) {
761                                                         SLOG(LOG_DEBUG, stt_tag(), "Old silence(%s), New silence(%s)", (char*)key_old, (char*)key_new);
762                                                         if (0 == xmlStrcmp(key_new, (const xmlChar*)"on")) {
763                                                                 *silence = 1;
764                                                         } else {
765                                                                 *silence = 0;
766                                                         }
767                                                 }
768
769                                                 xmlFree(key_new);
770                                         }
771                                         xmlFree(key_old);
772                                 }
773                         } else {
774                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
775                         }
776                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_CREDENTIAL)) {
777                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_CREDENTIAL)) {
778                                 key_old = xmlNodeGetContent(cur_old);
779                                 if (NULL != key_old) {
780                                         key_new = xmlNodeGetContent(cur_new);
781                                         if (NULL != key_new) {
782                                                 if (0 != xmlStrcmp(key_old, key_new)) {
783                                                         SLOG(LOG_DEBUG, stt_tag(), "Old credential(%s), New credential(%s)", (char*)key_old, (char*)key_new);
784                                                         if (0 == xmlStrcmp(key_new, (const xmlChar*)"true")) {
785                                                                 *credential = 1;
786                                                         } else {
787                                                                 *credential = 0;
788                                                         }
789                                                 }
790                                                 xmlFree(key_new);
791                                         }
792                                         xmlFree(key_old);
793                                 }
794                         } else {
795                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
796                         }
797
798                 } else {
799
800                 }
801
802                 cur_new = cur_new->next;
803                 cur_old = cur_old->next;
804         }
805
806         xmlFreeDoc(g_config_doc);
807         g_config_doc = doc;
808
809         return 0;
810 }
811
812 /**
813 * time function
814 */
815
816 int stt_parser_set_time_info(GSList* time_list)
817 {
818         if (0 == g_slist_length(time_list)) {
819                 SLOG(LOG_WARN, stt_tag(), "[WARNING] There is no time info to save");
820                 return -1;
821         }
822
823         if (-1 == remove(STT_TIME_INFO_PATH)) {
824                 SLOG(LOG_WARN, stt_tag(), "[PLAYER WARNING] Fail to remove file(%s)", STT_TIME_INFO_PATH);
825         }
826
827         xmlDocPtr doc = NULL;
828         xmlNodePtr cur = NULL;
829
830         doc = xmlNewDoc((const xmlChar*)"1.0");
831         if (doc == NULL) {
832                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make new doc");
833                 return -1;
834         }
835
836         cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_BASE_TAG);
837         xmlDocSetRootElement(doc, cur);
838
839         xmlNodePtr inode = NULL;
840         GSList *iter = NULL;
841         stt_result_time_info_s *data = NULL;
842         char temp_str[256];
843
844         snprintf(temp_str, 256, "%d", g_slist_length(time_list));
845
846         inode = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_INDEX);
847         xmlNewProp(inode, (const xmlChar*)STT_TAG_TIME_COUNT, (const xmlChar*)temp_str);
848         xmlAddChild(cur, inode);
849
850         /* Get a first item */
851         iter = g_slist_nth(time_list, 0);
852         while (NULL != iter) {
853                 data = iter->data;
854
855                 if (NULL == data) {
856                         SLOG(LOG_DEBUG, stt_tag(), "data is NULL");
857                         continue;
858                 }
859
860                 xmlNodePtr temp_node = NULL;
861
862                 SLOG(LOG_DEBUG, stt_tag(), "[%d] i(%d) t(%s) s(%d) e(%d)",
863                         data->index, data->event, data->text, data->start_time, data->end_time);
864
865                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_TEXT);
866                 xmlNodeSetContent(temp_node, (const xmlChar*)data->text);
867                 xmlAddChild(inode, temp_node);
868
869                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_START);
870                 snprintf(temp_str, 256, "%ld", data->start_time);
871                 xmlNodeSetContent(temp_node, (const xmlChar*)temp_str);
872                 xmlAddChild(inode, temp_node);
873
874                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_END);
875                 snprintf(temp_str, 256, "%ld", data->end_time);
876                 xmlNodeSetContent(temp_node, (const xmlChar*)temp_str);
877                 xmlAddChild(inode, temp_node);
878
879                 /*Get next item*/
880                 iter = g_slist_next(iter);
881         }
882
883         int ret = xmlSaveFormatFile(STT_TIME_INFO_PATH, doc, 1);
884         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
885
886         xmlFreeDoc(doc);
887         return 0;
888 }
889
890 int stt_parser_get_time_info(GSList** time_list)
891 {
892         if (NULL == time_list) {
893                 SLOG(LOG_ERROR, stt_tag(), "Invalid paramter : text is NULL");
894                 return -1;
895         }
896
897         xmlDocPtr doc = NULL;
898         xmlNodePtr cur = NULL;
899
900         doc = xmlParseFile(STT_TIME_INFO_PATH);
901         if (doc == NULL) {
902                 SLOG(LOG_WARN, stt_tag(), "[WARNING] File is not exist");
903                 return -1;
904         }
905
906         cur = xmlDocGetRootElement(doc);
907         if (cur == NULL) {
908                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
909                 xmlFreeDoc(doc);
910                 return -1;
911         }
912
913         if (xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_TIME_BASE_TAG)) {
914                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT '%s'", STT_TAG_TIME_BASE_TAG);
915                 xmlFreeDoc(doc);
916                 return -1;
917         }
918
919         cur = cur->xmlChildrenNode;
920         if (cur == NULL) {
921                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
922                 xmlFreeDoc(doc);
923                 return -1;
924         }
925
926         /* alloc time info */
927         GSList *temp_time_list = NULL;
928         xmlChar *key = NULL;
929         int index = 0;
930
931         while (cur != NULL) {
932                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_TIME_INDEX)) {
933                         key = xmlGetProp(cur, (const xmlChar*)STT_TAG_TIME_COUNT);
934                         if (NULL == key) {
935                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_COUNT);
936                                 return -1;
937                         }
938
939                         SLOG(LOG_DEBUG, stt_tag(), "Count : %s", (char *)key);
940
941                         /* Get time count */
942                         int count = 0;
943                         count = atoi((char*)key);
944                         xmlFree(key);
945
946                         if (count <= 0) {
947                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] count is invalid : %d", count);
948                                 break;
949                         }
950
951                         xmlNodePtr time_node = NULL;
952                         time_node = cur->xmlChildrenNode;
953
954                         int i = 0;
955                         for (i = 0; i < count; i++) {
956                                 /* text */
957                                 time_node = time_node->next;
958
959                                 stt_result_time_info_s* temp_info;
960                                 temp_info = (stt_result_time_info_s*)calloc(1, sizeof(stt_result_time_info_s));
961
962                                 if (NULL == temp_info) {
963                                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Memory alloc error!!");
964                                         return -1;
965                                 }
966
967                                 temp_info->index = index;
968                                 SLOG(LOG_DEBUG, stt_tag(), "index : %d", temp_info->index);
969
970                                 if (0 == i)             temp_info->event = 0;
971                                 else if (count -1 == i) temp_info->event = 2;
972                                 else                    temp_info->event = 1;
973
974                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_TEXT)) {
975                                         key = xmlNodeGetContent(time_node);
976                                         if (NULL != key) {
977                                                 SLOG(LOG_DEBUG, stt_tag(), "text : %s", (char *)key);
978                                                 temp_info->text = strdup((char*)key);
979                                                 xmlFree(key);
980                                         } else {
981                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_TEXT);
982                                                 free(temp_info);
983                                                 break;
984                                         }
985                                 }
986
987                                 /* text */
988                                 time_node = time_node->next;
989                                 time_node = time_node->next;
990
991                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_START)) {
992                                         key = xmlNodeGetContent(time_node);
993                                         if (NULL != key) {
994                                                 SLOG(LOG_DEBUG, stt_tag(), "Start time : %s", (char *)key);
995                                                 temp_info->start_time = atoi((char*)key);
996                                                 xmlFree(key);
997                                         } else {
998                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_START);
999                                                 if (NULL != temp_info->text)    free(temp_info->text);
1000                                                 free(temp_info);
1001                                                 break;
1002                                         }
1003                                 }
1004
1005                                 /* text */
1006                                 time_node = time_node->next;
1007                                 time_node = time_node->next;
1008
1009                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_END)) {
1010                                         key = xmlNodeGetContent(time_node);
1011                                         if (NULL != key) {
1012                                                 SLOG(LOG_DEBUG, stt_tag(), "End time : %s", (char *)key);
1013                                                 temp_info->end_time = atoi((char*)key);
1014                                                 xmlFree(key);
1015                                         } else {
1016                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_END);
1017                                                 if (NULL != temp_info->text)    free(temp_info->text);
1018                                                 free(temp_info);
1019                                                 break;
1020                                         }
1021                                 }
1022
1023                                 time_node = time_node->next;
1024
1025                                 temp_time_list = g_slist_append(temp_time_list, temp_info);
1026                         } /* for */
1027                         index++;
1028                 } /* if */
1029                 cur = cur->next;
1030         }
1031
1032         xmlFreeDoc(doc);
1033
1034         *time_list = temp_time_list;
1035
1036         return 0;
1037 }
1038
1039 int stt_parser_clear_time_info()
1040 {
1041         if (-1 == remove(STT_TIME_INFO_PATH)) {
1042                 /* SLOG(LOG_WARN, stt_tag(), "[PLAYER WARNING] Fail to remove file(%s)", STT_TIME_INFO_PATH); */
1043         }
1044
1045         return 0;
1046 }