Release version 0.1.60
[platform/core/uifw/tts.git] / server / ttsd_config_noti.c
1 /*
2 *  Copyright (c) 2012, 2013 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 <Ecore.h>
15 #include <Ecore_File.h>
16 #include <runtime_info.h>
17 #include <sys/inotify.h>
18 #include "ttsd_main.h"
19 #include "ttsd_config.h"
20 #include "ttsd_engine_agent.h"
21 #include "ttsd_data.h"
22
23 #define NOTI_ERROR_FILE_NAME            CONFIG_DIRECTORY"/ttsd_noti.err"
24
25 #define ENGINE_ID       "ENGINE_ID"
26 #define VOICE           "VOICE"
27 #define SPEED           "SPEED"
28
29 #define BUFFER_SIZE 20
30
31 static char*    g_engine_id;
32 static char*    g_language;
33 static int      g_vc_type;
34 static int      g_speed;
35
36 static Ecore_Fd_Handler* g_fd_handler_noti = NULL;
37 static int g_fd_noti;
38 static int g_wd_noti;
39
40 static ttsd_config_changed_cb g_callback;
41
42
43 int __ttsd_config_compare()
44 {
45         FILE* config_fp;
46         char buf_id[256] = {0};
47         char buf_param[256] = {0};
48         int int_param = 0;
49
50         config_fp = fopen(DEFAULT_CONFIG_FILE_NAME, "r");
51
52         if (NULL == config_fp) {
53                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Not open file(%s)", DEFAULT_CONFIG_FILE_NAME);
54
55                 return -1;
56         }
57
58         /* Read engine id */
59         if (EOF == fscanf(config_fp, "%s %s", buf_id, buf_param)) {
60                 fclose(config_fp);
61                 SLOG(LOG_ERROR, get_tag(), "[Config WARNING] Fail to read config (engine id)");
62                 return -1;
63         } else {
64                 if (0 == strncmp(ENGINE_ID, buf_id, strlen(ENGINE_ID))) {
65                         if (NULL != g_engine_id) {
66                                 if (0 != strcmp(g_engine_id, buf_param)) {
67                                         free(g_engine_id);
68                                         g_engine_id = strdup(buf_param);
69
70                                         SLOG(LOG_DEBUG, get_tag(), "[Config] engine id is changed : %s", g_engine_id);
71
72                                         if (NULL != g_callback)
73                                                 g_callback(TTS_CONFIG_TYPE_ENGINE, g_engine_id, 0);
74                                 }
75                         } else {
76                                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Current engine id is not available");
77                                 g_engine_id = strdup(buf_param);
78                                 if (NULL != g_callback)
79                                         g_callback(TTS_CONFIG_TYPE_ENGINE, g_engine_id, 0);
80                         }
81                 } else {
82                         fclose(config_fp);
83                         SLOG(LOG_ERROR, get_tag(), "[Config] Fail to load config (engine id)");
84                         return -1;
85                 }
86         }
87
88         /* Read voice */
89         if (EOF == fscanf(config_fp, "%s %s %d", buf_id, buf_param, &int_param)) {
90                 fclose(config_fp);
91                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to read config (voice)");
92                 return -1;
93         } else {
94                 if (0 == strncmp(VOICE, buf_id, strlen(VOICE))) {
95                         if (NULL != g_language) {
96                                 if ((0 != strcmp(g_language, buf_param)) || (g_vc_type != int_param)) {
97                                         free(g_language);
98                                         g_language = strdup(buf_param);
99                                         g_vc_type = int_param;
100
101                                         SLOG(LOG_DEBUG, get_tag(), "[Config] voice is changed : lang(%s) type(%d)", g_language, g_vc_type);
102
103                                         if (NULL != g_callback)
104                                                 g_callback(TTS_CONFIG_TYPE_VOICE, g_language, g_vc_type);
105                                 }
106                         } else {
107                                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Current voice is not available");
108                                 g_language = strdup(buf_param);
109                                 g_vc_type = int_param;
110
111                                 if (NULL != g_callback)
112                                         g_callback(TTS_CONFIG_TYPE_VOICE, g_language, g_vc_type);
113                         }
114                 } else {
115                         fclose(config_fp);
116                         SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to load config (voice)");
117                         return -1;
118                 }
119         }
120
121         /* Read speed */
122         if (EOF == fscanf(config_fp, "%s %d", buf_id, &int_param)) {
123                 fclose(config_fp);
124                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to read config (speed)");
125                 return -1;
126         } else {
127                 if (0 == strncmp(SPEED, buf_id, strlen(SPEED))) {
128                         if (g_speed != int_param) {
129                                 g_speed = int_param;
130
131                                 SLOG(LOG_DEBUG, get_tag(), "[Config] speech rate is changed : %d", g_speed);
132
133                                 if (NULL != g_callback)
134                                         g_callback(TTS_CONFIG_TYPE_SPEED, NULL, g_speed);
135                         }
136                 } else {
137                         fclose(config_fp);
138                         SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to load config (speed)");
139                         return -1;
140                 }
141         }
142
143         fclose(config_fp);
144
145         return 0;
146 }
147
148 int __ttsd_config_save()
149 {
150         if (0 != access(DEFAULT_CONFIG_FILE_NAME, R_OK|W_OK)) {
151                 if (0 == ecore_file_mkpath(CONFIG_DIRECTORY)) {
152                         SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to create directory (%s)", CONFIG_DIRECTORY);
153                 } else {
154                         SLOG(LOG_DEBUG, get_tag(), "[Config] Create directory (%s)", CONFIG_DIRECTORY);
155                 }
156         }
157
158         FILE* config_fp;
159         config_fp = fopen(DEFAULT_CONFIG_FILE_NAME, "w+");
160
161         if (NULL == config_fp) {
162                 /* make file and file default */
163                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to open config (%s)", DEFAULT_CONFIG_FILE_NAME);
164                 return -1;
165         }
166
167         SLOG(LOG_DEBUG, get_tag(), "[Config] Rewrite config file");
168
169         /* Write engine id */
170         fprintf(config_fp, "%s %s\n", ENGINE_ID, g_engine_id);
171
172         /* Write voice */
173         fprintf(config_fp, "%s %s %d\n", VOICE, g_language, g_vc_type);
174
175         /* Read speed */
176         fprintf(config_fp, "%s %d\n", SPEED, g_speed);
177
178         fclose(config_fp);
179
180         return 0;
181 }
182
183 int __ttsd_config_load()
184 {
185         FILE* config_fp;
186         char buf_id[256] = {0};
187         char buf_param[256] = {0};
188         int int_param = 0;
189         bool is_default_open = false;
190
191         config_fp = fopen(DEFAULT_CONFIG_FILE_NAME, "r");
192
193         if (NULL == config_fp) {
194                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Not open file(%s)", DEFAULT_CONFIG_FILE_NAME);
195
196                 config_fp = fopen(CONFIG_DEFAULT, "r");
197                 if (NULL == config_fp) {
198                         SLOG(LOG_ERROR, get_tag(), "[Config WARNING] Not open original config file(%s)", CONFIG_DEFAULT);
199                         return -1;
200                 }
201
202                 is_default_open = true;
203         }
204
205         /* Read engine id */
206         if (EOF == fscanf(config_fp, "%s %s", buf_id, buf_param)) {
207                 fclose(config_fp);
208                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to read config (engine id)");
209                 return -1;
210         } else {
211                 if (0 == strncmp(ENGINE_ID, buf_id, strlen(ENGINE_ID))) {
212                         g_engine_id = strdup(buf_param);
213                 } else {
214                         fclose(config_fp);
215                         SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to load config (engine id)");
216                         return -1;
217                 }
218         }
219
220         /* Read voice */
221         if (EOF == fscanf(config_fp, "%s %s %d", buf_id, buf_param, &int_param)) {
222                 fclose(config_fp);
223                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to read config (voice)");
224                 __ttsd_config_save();
225                 return -1;
226         } else {
227                 if (0 == strncmp(VOICE, buf_id, strlen(VOICE))) {
228                         g_language = strdup(buf_param);
229                         g_vc_type = int_param;
230                 } else {
231                         fclose(config_fp);
232                         SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to load config (voice)");
233                         return -1;
234                 }
235         }
236
237         /* Read speed */
238         if (EOF == fscanf(config_fp, "%s %d", buf_id, &int_param)) {
239                 fclose(config_fp);
240                 SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to read config (speed)");
241                 return -1;
242         } else {
243                 if (0 == strncmp(SPEED, buf_id, strlen(SPEED))) {
244                         g_speed = int_param;
245                 } else {
246                         fclose(config_fp);
247                         SLOG(LOG_WARN, get_tag(), "[Config WARNING] Fail to load config (speed)");
248                         return -1;
249                 }
250         }
251
252         fclose(config_fp);
253
254         SLOG(LOG_DEBUG, get_tag(), "[Config] Load config : engine(%s), voice(%s,%d), speed(%d)",
255                 g_engine_id, g_language, g_vc_type, g_speed);
256
257         if (true == is_default_open) {
258                 if(0 == __ttsd_config_save()) {
259                         SLOG(LOG_DEBUG, get_tag(), "[Config] Create config(%s)", DEFAULT_CONFIG_FILE_NAME);
260                 }
261         }
262
263         return 0;
264 }
265
266 static Eina_Bool inotify_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
267 {
268         SLOG(LOG_DEBUG, get_tag(), "===== [Config] Inotify event call");
269
270         int length;
271
272         char buffer[sizeof(struct inotify_event) * BUFFER_SIZE];
273         memset(buffer, 0, (sizeof(struct inotify_event) * BUFFER_SIZE));
274
275         length = read(g_fd_noti, buffer, (sizeof(struct inotify_event) * BUFFER_SIZE));
276         if (0 > length) {
277                 SLOG(LOG_ERROR, get_tag(), "[Config] Empty Inotify event");
278                 SLOG(LOG_DEBUG, get_tag(), "=====");
279                 SLOG(LOG_DEBUG, get_tag(), " ");
280                 return ECORE_CALLBACK_RENEW; 
281         }
282
283         FILE *fp;
284
285         int i = 0;
286         while (i < length) {
287                 char text[256];
288                 char msg[256];
289                 int uid, send_data;
290
291                 struct inotify_event *event = (struct inotify_event *)&buffer[i];
292                 i = i + sizeof(struct inotify_event) + event->len;
293
294                 if (IN_CLOSE_WRITE == event->mask) {
295                         __ttsd_config_compare();
296                 } else {
297                         SLOG(LOG_ERROR, get_tag(), "[Config] Undefined event");
298                 }
299         }
300
301         SLOG(LOG_DEBUG, get_tag(), "=====");
302         SLOG(LOG_DEBUG, get_tag(), " ");
303
304         return ECORE_CALLBACK_PASS_ON;
305 }
306
307 int __config_file_open_connection()
308 {
309         /* get file notification handler */
310         int fd;
311         int wd;
312
313         fd = inotify_init();
314         if (fd < 0) {
315                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Fail get inotify_fd");
316                 return -1;
317         }
318         g_fd_noti = fd;
319
320         wd = inotify_add_watch(fd, DEFAULT_CONFIG_FILE_NAME, IN_CLOSE_WRITE);
321         g_wd_noti = wd;
322         g_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)inotify_event_callback, NULL, NULL, NULL);                
323         if (NULL == g_fd_handler_noti) {
324                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Fail to get handler_noti");
325                 return -1;
326         }
327
328         return 0;
329 }
330
331 int ttsd_config_initialize(ttsd_config_changed_cb callback)
332 {
333         g_engine_id = NULL;
334         g_language = NULL;
335         g_vc_type = 1;
336         g_speed = 3;
337
338         g_callback = callback;
339
340         ecore_file_mkpath(CONFIG_DIRECTORY);
341
342         __ttsd_config_load();
343
344         if (0 != __config_file_open_connection()) {
345                 return -1;
346         }
347
348         return 0;
349 }
350
351 int ttsd_config_finalize()
352 {
353         if (NULL != g_language) {
354                 free(g_language);
355         }
356
357         if (NULL != g_engine_id) {
358                 free(g_engine_id);
359         }
360
361         /* del inotify variable */
362         ecore_main_fd_handler_del(g_fd_handler_noti);
363         inotify_rm_watch(g_fd_noti, g_wd_noti);
364         close(g_fd_noti);
365
366         return 0;
367 }
368
369 int ttsd_config_update_language()
370 {
371         /* no work in notification mode */
372         return 0;
373 }
374
375 int ttsd_config_get_default_engine(char** engine_id)
376 {
377         if (NULL == engine_id)
378                 return -1;
379
380         if (NULL != g_engine_id) {
381                 *engine_id = strdup(g_engine_id);
382         } else {
383                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Current engine id is NULL");
384                 return -1;
385         }
386
387         return 0;
388 }
389
390 int ttsd_config_set_default_engine(const char* engine_id)
391 {
392         /* Not available in notification mode */
393         return 0;
394 }
395
396 int ttsd_config_get_default_voice(char** language, int* type)
397 {
398         if (NULL == language || NULL == type)
399                 return -1;
400
401         if (NULL != g_language) {
402                 *language = strdup(g_language);
403                 *type = g_vc_type;
404         } else {
405                 SLOG(LOG_ERROR, get_tag(), "[Config ERROR] Current language is NULL");
406                 return -1;
407         }
408         
409         return 0;
410 }
411
412 int ttsd_config_set_default_voice(const char* language, int type)
413 {
414         /* Not available in notification mode */
415         return 0;
416 }
417
418 int ttsd_config_get_default_speed(int* speed)
419 {
420         if (NULL == speed)
421                 return -1;
422
423         *speed = g_speed;
424
425         return 0;
426 }
427
428 int ttsd_config_set_default_speed(int speed)
429 {
430         /* Not available in notification mode */
431         return 0;
432 }
433
434 int ttsd_config_save_error(int uid, int uttid, const char* lang, int vctype, const char* text, 
435                            const char* func, int line, const char* message)
436 {
437         FILE* err_fp;
438         err_fp = fopen(NOTI_ERROR_FILE_NAME, "a");
439         if (NULL == err_fp) {
440                 SLOG(LOG_WARN, get_tag(), "[WARNING] Fail to open error file (%s)", NOTI_ERROR_FILE_NAME);
441                 return -1;
442         }
443         SLOG(LOG_DEBUG, get_tag(), "Save Error File (%s)", NOTI_ERROR_FILE_NAME);
444
445         /* func */
446         if (NULL != func) {
447                 fprintf(err_fp, "function - %s\n", func);
448         }
449         
450         /* line */
451         fprintf(err_fp, "line - %d\n", line);
452
453         /* message */
454         if (NULL != message) {
455                 fprintf(err_fp, "message - %s\n", message);
456         }
457
458         int ret;
459         /* uid */
460         fprintf(err_fp, "uid - %d\n", uid);
461         
462         /* uttid */
463         fprintf(err_fp, "uttid - %d\n", uttid);
464
465         /* lang */
466         if (NULL != lang) {
467                 fprintf(err_fp, "language - %s\n", lang);
468         }
469
470         /* vctype */
471         fprintf(err_fp, "vctype - %d\n", vctype);
472
473         /* text */
474         if (NULL != text) {
475                 fprintf(err_fp, "text - %s\n", text);
476         }
477
478         /* get current engine */
479         char *engine_id = NULL;
480
481         ret = ttsd_engine_setting_get_engine(&engine_id);
482         if (0 != ret) {
483                 SLOG(LOG_ERROR, get_tag(), "[ERROR] Fail to get current engine");
484         } else {
485                 fprintf(err_fp, "current engine - %s", engine_id);
486         }
487
488         /* get data */
489         ttsd_data_save_error_log(uid, err_fp);
490
491         fclose(err_fp);
492
493         return 0;
494 }