Tizen 2.1 base
[platform/core/uifw/stt.git] / server / sttd_server.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
15 #include "sttd_main.h"
16 #include "sttd_server.h"
17
18 #include "sttd_client_data.h"
19 #include "sttd_engine_agent.h"
20 #include "sttd_config.h"
21 #include "sttd_recorder.h"
22 #include "sttd_network.h"
23 #include "sttd_dbus.h"
24
25 /*
26 * STT Server static variable
27 */
28 static bool g_is_engine;
29
30 static double g_state_check_time = 15.5;
31
32 /*
33 * STT Server Callback Functions                                                                                 `                                 *
34 */
35
36 Eina_Bool __stop_by_silence(void *data)
37 {
38         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
39
40         int uid = 0;
41
42         uid = sttd_client_get_current_recording();
43
44         if (uid > 0) {
45                 if (0 != sttd_server_stop(uid))
46                         return EINA_FALSE;
47
48                 int ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
49                 if (0 != ret) {
50                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret); 
51
52                         /* Remove client */
53                         sttd_server_finalize(uid);
54                 }       
55         }
56
57         SLOG(LOG_DEBUG, TAG_STTD, "=====");
58         SLOG(LOG_DEBUG, TAG_STTD, "  ");
59
60         return EINA_FALSE;
61 }
62
63 int audio_recorder_callback(const void* data, const unsigned int length)
64 {
65         if (0 != sttd_engine_recognize_audio(data, length)) {
66                 int uid = sttd_client_get_current_recording();
67
68                 app_state_e state;
69                 if (0 != sttd_client_get_state(uid, &state)) {
70                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid "); 
71                         return -1;
72                 }
73
74                 if (APP_STATE_RECORDING != state) {
75                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
76                         return -1;
77                 }
78
79                 ecore_timer_add(0, __stop_by_silence, NULL);
80
81                 /*if (0 != sttd_send_stop_recognition_by_daemon(uid)) {
82                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail "); 
83                 } else {
84                         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] <<<< stop message : uid(%d)", uid); 
85                 }*/
86                 
87                 return -1;
88         }
89
90         return 0;
91 }
92
93 void sttd_server_recognition_result_callback(sttp_result_event_e event, const char* type, 
94                                         const char** data, int data_count, const char* msg, void *user_data)
95 {
96         SLOG(LOG_DEBUG, TAG_STTD, "===== Recognition Result Callback");
97
98         if (NULL == user_data) {
99                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] user data is NULL"); 
100                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
101                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
102                 return;
103         }
104
105         /* check uid */
106         int *uid = (int*)user_data;
107
108         SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", *uid, event); 
109
110         app_state_e state;
111         if (0 != sttd_client_get_state(*uid, &state)) {
112                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
113                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
114                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
115                 return;
116         }
117
118         /* Delete timer for processing time out */
119         Ecore_Timer* timer;
120         sttd_cliet_get_timer(*uid, &timer);
121
122         if (NULL != timer)
123                 ecore_timer_del(timer);
124
125         /* send result to client */
126         if (STTP_RESULT_EVENT_SUCCESS == event && 0 < data_count && NULL != data) {
127
128                 if (APP_STATE_PROCESSING == state ) {
129                         SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d' %s", data_count); 
130
131                         if (0 != sttdc_send_result(*uid, type, data, data_count, msg)) {
132                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");        
133                                 int reason = (int)STTD_ERROR_OPERATION_FAILED;
134
135                                 if (0 != sttdc_send_error_signal(*uid, reason, "Fail to send recognition result")) {
136                                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data"); 
137                                 }
138                         }
139                 } else {
140                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT thinking."); 
141                 }
142         } else if (STTP_RESULT_EVENT_NO_RESULT == event || STTP_RESULT_EVENT_ERROR == event) {
143
144                 if (APP_STATE_PROCESSING == state ) {
145                         if (0 != sttdc_send_result(*uid, type, NULL, 0, msg)) {
146                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result "); 
147
148                                 /* send error msg */
149                                 int reason = (int)STTD_ERROR_INVALID_STATE;     
150                                 if (0 != sttdc_send_error_signal(*uid, reason, "[ERROR] Fail to send recognition result")) {
151                                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info "); 
152                                 }
153                         }
154                 } else {
155                         SLOG(LOG_WARN, TAG_STTD, "[Server ERROR] Current state is NOT thinking."); 
156                 }
157         } else {
158                 /* nothing */
159         }
160
161         /* change state of uid */
162         sttd_client_set_state(*uid, APP_STATE_READY);
163
164         if (NULL != user_data)  
165                 free(user_data);
166
167         SLOG(LOG_DEBUG, TAG_STTD, "=====");
168         SLOG(LOG_DEBUG, TAG_STTD, "  ");
169
170         return;
171 }
172
173 void sttd_server_partial_result_callback(sttp_result_event_e event, const char* data, void *user_data)
174 {
175         SLOG(LOG_DEBUG, TAG_STTD, "===== Partial Result Callback");
176
177         /* check uid */
178         int *uid = (int*)user_data;
179
180         SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event); 
181
182         app_state_e state;
183         if (0 != sttd_client_get_state(*uid, &state)) {
184                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
185                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
186                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
187                 return;
188         }
189
190         /* send result to client */
191         if (STTP_RESULT_EVENT_SUCCESS == event && NULL != data) {
192                 if (0 != sttdc_send_partial_result(*uid, data)) {
193                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send partial result");        
194                 }
195         } 
196
197         SLOG(LOG_DEBUG, TAG_STTD, "=====");
198         SLOG(LOG_DEBUG, TAG_STTD, "  ");
199 }
200
201 void sttd_server_silence_dectection_callback(void *user_param)
202 {
203         SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
204
205         int uid = sttd_client_get_current_recording();
206
207         app_state_e state;
208         if (0 != sttd_client_get_state(uid, &state)) {
209                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid "); 
210                 return;
211         }
212
213         if (APP_STATE_RECORDING != state) {
214                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
215                 return;
216         }
217
218         ecore_timer_add(0, __stop_by_silence, NULL);
219
220         SLOG(LOG_DEBUG, TAG_STTD, "=====");
221         SLOG(LOG_DEBUG, TAG_STTD, "  ");
222
223         return;
224 }
225
226 /*
227 * Daemon function
228 */
229
230 int sttd_initialize()
231 {
232         int ret = 0;
233
234         if (sttd_config_initialize()) {
235                 SLOG(LOG_ERROR, TAG_STTD, "[Server WARNING] Fail to initialize config.");
236         }
237
238         /* recoder init */
239         ret = sttd_recorder_init();
240         if (0 != ret) {
241                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret); 
242                 return ret;
243         }
244
245         /* Engine Agent initialize */
246         ret = sttd_engine_agent_init(sttd_server_recognition_result_callback, sttd_server_partial_result_callback, 
247                                 sttd_server_silence_dectection_callback);
248         if (0 != ret) {
249                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
250                 return ret;
251         }
252         
253         if (0 != sttd_engine_agent_initialize_current_engine()) {
254                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is No STT-Engine !!!!!"); 
255                 g_is_engine = false;
256         } else {
257                 g_is_engine = true;
258         }
259
260         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize"); 
261
262         return 0;
263 }
264
265 Eina_Bool sttd_cleanup_client(void *data)
266 {
267         int* client_list = NULL;
268         int client_count = 0;
269
270         if (0 != sttd_client_get_list(&client_list, &client_count)) 
271                 return EINA_TRUE;
272         
273         if (NULL == client_list)
274                 return EINA_TRUE;
275
276         int result;
277         int i = 0;
278
279         SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
280
281         for (i = 0;i < client_count;i++) {
282                 result = sttdc_send_hello(client_list[i]);
283
284                 if (0 == result) {
285                         SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]); 
286                         sttd_server_finalize(client_list[i]);
287                 } else if (-1 == result) {
288                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error"); 
289                 }
290         }
291
292         SLOG(LOG_DEBUG, TAG_STTD, "=====");
293         SLOG(LOG_DEBUG, TAG_STTD, "  ");
294
295         free(client_list);
296
297         return EINA_TRUE;
298 }
299
300 /*
301 * STT Server Functions for Client
302 */
303
304 int sttd_server_initialize(int pid, int uid, bool* silence, bool* profanity, bool* punctuation)
305 {
306         if (false == g_is_engine) {
307                 if (0 != sttd_engine_agent_initialize_current_engine()) {
308                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] No Engine"); 
309                         g_is_engine = false;
310                         return STTD_ERROR_ENGINE_NOT_FOUND;
311                 } else {
312                         g_is_engine = true;
313                 }
314         }
315
316         /* check if uid is valid */
317         app_state_e state;
318         if (0 == sttd_client_get_state(uid, &state)) {
319                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid has already been registered"); 
320                 return STTD_ERROR_INVALID_PARAMETER;
321         }
322         
323         /* load if engine is unloaded */
324         if (0 == sttd_client_get_ref_count()) {
325                 if (0 != sttd_engine_agent_load_current_engine()) {
326                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load current engine"); 
327                         return STTD_ERROR_OPERATION_FAILED;
328                 }
329         }
330
331         /* initialize recorder using audio format from engine */
332         sttp_audio_type_e atype;
333         int rate;
334         int channels;
335
336         if (0 != sttd_engine_get_audio_format(&atype, &rate, &channels)) {
337                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get audio format of engine."); 
338                 return STTD_ERROR_OPERATION_FAILED;
339         }
340
341         sttd_recorder_channel           sttchannel = STTD_RECORDER_CHANNEL_MONO;
342         sttd_recorder_audio_type        sttatype = STTD_RECORDER_PCM_S16;
343
344         switch (atype) {
345         case STTP_AUDIO_TYPE_PCM_S16_LE:        sttatype = STTD_RECORDER_PCM_S16;       break;
346         case STTP_AUDIO_TYPE_PCM_U8:            sttatype = STTD_RECORDER_PCM_U8;        break;
347         case STTP_AUDIO_TYPE_AMR:               sttatype = STTD_RECORDER_AMR;           break;
348         default:        
349                 /* engine error */
350                 sttd_engine_agent_unload_current_engine();
351                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Invalid Audio Type"); 
352                 return STTD_ERROR_OPERATION_FAILED;
353                 break;
354         }
355
356         switch (channels) {
357         case 1:         sttchannel = STTD_RECORDER_CHANNEL_MONO;        break;
358         case 2:         sttchannel = STTD_RECORDER_CHANNEL_STEREO;      break;
359         default:        sttchannel = STTD_RECORDER_CHANNEL_MONO;        break;
360         }
361
362         if (0 != sttd_recorder_set(sttatype, sttchannel, rate, 60, audio_recorder_callback)) {
363                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set recorder"); 
364                 return STTD_ERROR_OPERATION_FAILED;
365         }
366         
367         SLOG(LOG_DEBUG, TAG_STTD, "[Server] audio type(%d), channel(%d)", (int)atype, (int)sttchannel); 
368
369         /* Add client information to client manager */
370         if (0 != sttd_client_add(pid, uid)) {
371                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info"); 
372                 return STTD_ERROR_OPERATION_FAILED;
373         }
374
375         if (0 != sttd_engine_get_option_supported(silence, profanity, punctuation)) {
376                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported"); 
377                 return STTD_ERROR_OPERATION_FAILED;
378         }
379
380         SLOG(LOG_DEBUG, TAG_STTD, "[Server Success] Initialize"); 
381
382         return STTD_ERROR_NONE;
383 }
384
385 int sttd_server_finalize(const int uid)
386 {
387         /* check if uid is valid */
388         app_state_e state;
389         if (0 != sttd_client_get_state(uid, &state)) {
390                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
391                 return STTD_ERROR_INVALID_PARAMETER;
392         }
393
394         /* release recorder */
395         if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
396                 sttd_recorder_cancel();
397                 sttd_engine_recognize_cancel();
398         }
399         
400         /* Remove client information */
401         if (0 != sttd_client_delete(uid)) {
402                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client"); 
403         }
404
405         /* unload engine, if ref count of client is 0 */
406         if (0 == sttd_client_get_ref_count()) {
407                 if (0 != sttd_engine_agent_unload_current_engine()) {
408                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload current engine"); 
409                 } else {
410                         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] unload current engine"); 
411                 }
412         }
413         
414         return STTD_ERROR_NONE;
415 }
416
417 int sttd_server_get_supported_languages(const int uid, GList** lang_list)
418 {
419         /* check if uid is valid */
420         app_state_e state;
421         if (0 != sttd_client_get_state(uid, &state)) {
422                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
423                 return STTD_ERROR_INVALID_PARAMETER;
424         }
425
426         /* get language list from engine */
427         int ret = sttd_engine_supported_langs(lang_list);
428         if (0 != ret) {
429                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages"); 
430                 return STTD_ERROR_OPERATION_FAILED;
431         }
432
433         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages"); 
434
435         return STTD_ERROR_NONE;
436 }
437
438 int sttd_server_get_current_langauage(const int uid, char** current_lang)
439 {
440         /* check if uid is valid */
441         app_state_e state;
442         if (0 != sttd_client_get_state(uid, &state)) {
443                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
444                 return STTD_ERROR_INVALID_PARAMETER;
445         }
446
447         if (NULL == current_lang) {
448                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
449                 return STTD_ERROR_INVALID_PARAMETER;
450         }
451
452         /*get current language from engine */
453         int ret = sttd_engine_get_default_lang(current_lang);
454         if (0 != ret) { 
455                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret); 
456                 return STTD_ERROR_OPERATION_FAILED;
457         }
458
459         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_engine_get_default_lang"); 
460
461         return STTD_ERROR_NONE;
462 }
463
464 int sttd_server_is_partial_result_supported(int uid, int* partial_result)
465 {
466         /* check if uid is valid */
467         app_state_e state;
468         if (0 != sttd_client_get_state(uid, &state)) {
469                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
470                 return STTD_ERROR_INVALID_PARAMETER;
471         }
472
473         if (NULL == partial_result) {
474                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
475                 return STTD_ERROR_INVALID_PARAMETER;
476         }
477
478         bool temp;
479         int ret = sttd_engine_is_partial_result_supported(&temp);
480         if (0 != ret) { 
481                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get partial result supported : result(%d)", ret); 
482                 return STTD_ERROR_OPERATION_FAILED;
483         }
484
485         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Partial result supporting is %s", temp ? "true" : "false"); 
486
487         return STTD_ERROR_NONE;
488 }
489
490 int sttd_server_get_audio_volume( const int uid, float* current_volume)
491 {
492         /* check if uid is valid */
493         app_state_e state;
494         if (0 != sttd_client_get_state(uid, &state)) {
495                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
496                 return STTD_ERROR_INVALID_PARAMETER;
497         }
498
499         /* check uid state */
500         if (APP_STATE_RECORDING != state) {
501                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
502                 return STTD_ERROR_INVALID_STATE;
503         }
504
505         if (NULL == current_volume) {
506                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
507                 return STTD_ERROR_INVALID_PARAMETER;
508         }
509
510         /* get audio volume from recorder */
511         int ret = sttd_recorder_get_volume(current_volume);
512         if (0 != ret) {
513                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get volume : result(%d)", ret); 
514                 return STTD_ERROR_OPERATION_FAILED;
515         }
516
517         return STTD_ERROR_NONE;
518 }
519
520 Eina_Bool __check_recording_state(void *data)
521 {       
522         /* current uid */
523         int uid = sttd_client_get_current_recording();
524         if (-1 == uid)
525                 return EINA_FALSE;
526
527         app_state_e state;
528         if (0 != sttdc_send_get_state(uid, (int*)&state)) {
529                 /* client is removed */
530                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid); 
531                 sttd_server_finalize(uid);
532                 return EINA_FALSE;
533         }
534
535         if (APP_STATE_READY == state) {
536                 /* Cancel stt */
537                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid); 
538                 sttd_server_cancel(uid);
539         } else if (APP_STATE_PROCESSING == state) {
540                 /* Cancel stt and send change state */
541                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid); 
542                 sttd_server_cancel(uid);
543                 sttdc_send_set_state(uid, (int)APP_STATE_READY);
544         } else {
545                 /* Normal state */
546                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical"); 
547                 return EINA_TRUE;
548         }
549
550         return EINA_FALSE;
551 }
552
553 int sttd_server_start(const int uid, const char* lang, const char* recognition_type, 
554                       int profanity, int punctuation, int silence)
555 {
556         /* check if uid is valid */
557         app_state_e state;
558         if (0 != sttd_client_get_state(uid, &state)) {
559                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
560                 return STTD_ERROR_INVALID_PARAMETER;
561         }
562
563         /* check uid state */
564         if (APP_STATE_READY != state) {
565                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready"); 
566                 return STTD_ERROR_INVALID_STATE;
567         }
568
569         if (0 < sttd_client_get_current_recording()) {
570                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT Engine is busy because of recording");
571                 return STTD_ERROR_RECORDER_BUSY;
572         }
573
574         if (0 < sttd_client_get_current_thinking()) {
575                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT Engine is busy because of thinking");
576                 return STTD_ERROR_RECORDER_BUSY;
577         }
578
579         /* check if engine use network */
580         if (true == sttd_engine_agent_need_network()) {
581                 if (false == sttd_network_is_connected()) {
582                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
583                         return STTD_ERROR_OUT_OF_NETWORK;
584                 }
585         }
586
587         /* engine start recognition */
588         int* user_data;
589         user_data = (int*)malloc( sizeof(int) * 1);
590         
591         /* free on result callback */
592         *user_data = uid;
593
594         SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)", *user_data, lang, recognition_type ); 
595
596         int ret = sttd_engine_recognize_start((char*)lang, recognition_type, profanity, punctuation, silence, (void*)user_data);
597         if (0 != ret) {
598                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret); 
599                 return STTD_ERROR_OPERATION_FAILED;
600         }
601
602         /* recorder start */
603         ret = sttd_recorder_start();
604         if (0 != ret) {
605                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret); 
606                 sttd_engine_recognize_cancel();
607                 return STTD_ERROR_OPERATION_FAILED;
608         }
609
610         SLOG(LOG_DEBUG, TAG_STTD, "[Server] start recording"); 
611
612         /* change uid state */
613         sttd_client_set_state(uid, APP_STATE_RECORDING);
614
615         Ecore_Timer* timer = ecore_timer_add(g_state_check_time, __check_recording_state, NULL);
616         sttd_cliet_set_timer(uid, timer);
617
618         return STTD_ERROR_NONE;
619 }
620
621 Eina_Bool __time_out_for_processing(void *data)
622 {       
623         /* current uid */
624         int uid = sttd_client_get_current_thinking();
625         if (-1 == uid)
626                 return EINA_FALSE;
627
628         /* Cancel engine */
629         int ret = sttd_engine_recognize_cancel();
630         if (0 != ret) {
631                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret); 
632         }
633
634         if (0 != sttdc_send_result(uid, STTP_RECOGNITION_TYPE_FREE, NULL, 0, "Time out not to receive recognition result.")) {
635                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result "); 
636
637                 /* send error msg */
638                 int reason = (int)STTD_ERROR_TIMED_OUT; 
639                 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
640                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info "); 
641                 }
642         }
643
644         /* Change uid state */
645         sttd_client_set_state(uid, APP_STATE_READY);
646
647         return EINA_FALSE;
648 }
649
650
651 int sttd_server_stop(const int uid)
652 {
653         /* check if uid is valid */
654         app_state_e state;
655         if (0 != sttd_client_get_state(uid, &state)) {
656                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
657                 return STTD_ERROR_INVALID_PARAMETER;
658         }
659
660         /* check uid state */
661         if (APP_STATE_RECORDING != state) {
662                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
663                 return STTD_ERROR_INVALID_STATE;
664         }
665
666         /* stop recorder */
667         sttd_recorder_stop();
668
669         /* stop engine recognition */
670         int ret = sttd_engine_recognize_stop();
671         if (0 != ret) {
672                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret); 
673                 sttd_client_set_state(uid, APP_STATE_READY);            
674         
675                 return STTD_ERROR_OPERATION_FAILED;
676         }
677         
678         Ecore_Timer* timer;
679         sttd_cliet_get_timer(uid, &timer);
680
681         if (NULL != timer)
682                 ecore_timer_del(timer);
683
684         /* change uid state */
685         sttd_client_set_state(uid, APP_STATE_PROCESSING);
686
687         timer = ecore_timer_add(g_state_check_time, __time_out_for_processing, NULL);
688         sttd_cliet_set_timer(uid, timer);
689
690         return STTD_ERROR_NONE;
691 }
692
693 int sttd_server_cancel(const int uid)
694 {
695         /* check if uid is valid */
696         app_state_e state;
697         if (0 != sttd_client_get_state(uid, &state)) {
698                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
699                 return STTD_ERROR_INVALID_PARAMETER;
700         }
701
702         /* check uid state */ 
703         if (APP_STATE_READY == state) {
704                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready"); 
705                 return STTD_ERROR_INVALID_STATE;
706         }
707
708         /* stop recorder */
709         if (APP_STATE_RECORDING == state) 
710                 sttd_recorder_cancel();
711
712         /* cancel engine recognition */
713         int ret = sttd_engine_recognize_cancel();
714         if (0 != ret) {
715                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret); 
716                 return STTD_ERROR_OPERATION_FAILED;
717         }
718
719         Ecore_Timer* timer;
720         sttd_cliet_get_timer(uid, &timer);
721         ecore_timer_del(timer);
722
723         /* change uid state */
724         sttd_client_set_state(uid, APP_STATE_READY);
725
726         return STTD_ERROR_NONE;
727 }
728
729
730 /******************************************************************************************
731 * STT Server Functions for setting
732 *******************************************************************************************/
733
734 int sttd_server_setting_initialize(int pid)
735 {
736         if (false == g_is_engine) {
737                 if (0 != sttd_engine_agent_initialize_current_engine()) {
738                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] No Engine"); 
739                         g_is_engine = false;
740                         return STTD_ERROR_ENGINE_NOT_FOUND;
741                 } else {
742                         g_is_engine = true;
743                 }
744         }
745
746         /* check whether pid is valid */
747         if (true == sttd_setting_client_is(pid)) {
748                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
749                 return STTD_ERROR_INVALID_PARAMETER;
750         }
751
752         /* load if engine is unloaded */
753         if (0 == sttd_client_get_ref_count()) {
754                 if (0 != sttd_engine_agent_load_current_engine()) {
755                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load current engine"); 
756                         return STTD_ERROR_OPERATION_FAILED;
757                 }
758         }
759
760         /* Add setting client information to client manager (For internal use) */
761         if (0 != sttd_setting_client_add(pid)) {
762                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add setting client"); 
763                 return STTD_ERROR_OPERATION_FAILED;
764         }
765
766         return STTD_ERROR_NONE;
767 }
768
769 int sttd_server_setting_finalize(int pid)
770 {
771         /* Remove client information */
772         if (0 != sttd_setting_client_delete(pid)) {
773                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete setting client"); 
774         }
775
776         /* unload engine, if ref count of client is 0 */
777         if (0 == sttd_client_get_ref_count()) {
778                 if (0 != sttd_engine_agent_unload_current_engine()) {
779                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload current engine"); 
780                 } else {
781                         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] unload current engine"); 
782                 }
783         }
784
785         return STTD_ERROR_NONE;
786 }
787
788 int sttd_server_setting_get_engine_list(int pid, GList** engine_list)
789 {
790         /* check whether pid is valid */
791         if (true != sttd_setting_client_is(pid)) {
792                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
793                 return STTD_ERROR_INVALID_PARAMETER;
794         }
795
796         if (NULL == engine_list) {
797                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
798                 return STTD_ERROR_INVALID_PARAMETER;
799         }
800
801         int ret = sttd_engine_setting_get_engine_list(engine_list); 
802         if (0 != ret) {
803                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list : result(%d)", ret); 
804                 return ret;
805         }
806
807         return STTD_ERROR_NONE;
808 }
809
810 int sttd_server_setting_get_engine(int pid, char** engine_id)
811 {
812         /* check whether pid is valid */
813         if (true != sttd_setting_client_is(pid)) {
814                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
815                 return STTD_ERROR_INVALID_PARAMETER;
816         }
817
818         if (NULL == engine_id) {
819                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
820                 return STTD_ERROR_INVALID_PARAMETER;
821         }
822
823         /* get engine */
824         int ret = sttd_engine_setting_get_engine(engine_id); 
825         if (0 != ret) {
826                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : result(%d)", ret); 
827                 return ret;
828         }
829
830         return STTD_ERROR_NONE;
831 }
832
833 int sttd_server_setting_set_engine(int pid, const char* engine_id)
834 {
835         /* check whether pid is valid */
836         if (true != sttd_setting_client_is(pid)) {
837                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
838                 return STTD_ERROR_INVALID_PARAMETER;
839         }
840
841         if (NULL == engine_id) {
842                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
843                 return STTD_ERROR_INVALID_PARAMETER;
844         }
845
846         /* set engine */
847         int ret = sttd_engine_setting_set_engine(engine_id); 
848         if (0 != ret) {
849                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret); 
850                 return ret;
851         }
852
853         return STTD_ERROR_NONE;
854 }
855
856 int sttd_server_setting_get_lang_list(int pid, char** engine_id, GList** lang_list)
857 {
858         /* check whether pid is valid */
859         if (true != sttd_setting_client_is(pid)) {
860                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
861                 return STTD_ERROR_INVALID_PARAMETER;
862         }
863         
864         if (NULL == lang_list) {
865                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL"); 
866                 return STTD_ERROR_INVALID_PARAMETER;
867         }
868         
869         int ret = sttd_engine_setting_get_lang_list(engine_id, lang_list); 
870         if (0 != ret) {
871                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get language list : result(%d)", ret); 
872                 return ret;
873         }
874
875         return STTD_ERROR_NONE;
876 }
877
878 int sttd_server_setting_get_default_language(int pid, char** language)
879 {
880         /* check whether pid is valid */
881         if (true != sttd_setting_client_is(pid)) {
882                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
883                 return STTD_ERROR_INVALID_PARAMETER;
884         }
885
886         if (NULL == language) {
887                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL"); 
888                 return STTD_ERROR_INVALID_PARAMETER;
889         }
890
891         int ret = sttd_engine_setting_get_default_lang(language); 
892         if (0 != ret) {
893                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language : result(%d)", ret); 
894                 return ret;
895         }       
896
897         return STTD_ERROR_NONE;
898 }
899
900 int sttd_server_setting_set_default_language(int pid, const char* language)
901 {
902         /* check whether pid is valid */
903         if (true != sttd_setting_client_is(pid)) {
904                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
905                 return STTD_ERROR_INVALID_PARAMETER;
906         }
907
908         if (NULL == language) {
909                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL"); 
910                 return STTD_ERROR_INVALID_PARAMETER;
911         }
912
913         int ret = sttd_engine_setting_set_default_lang((char*)language); 
914         if (0 != ret) {
915                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret); 
916                 return ret;
917         }       
918
919         return STTD_ERROR_NONE;
920 }
921
922 int sttd_server_setting_get_profanity_filter(int pid, bool* value)
923 {
924         /* check whether pid is valid */
925         if (true != sttd_setting_client_is(pid)) {
926                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
927                 return STTD_ERROR_INVALID_PARAMETER;
928         }
929
930         if (NULL == value) {
931                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
932                 return STTD_ERROR_INVALID_PARAMETER;
933         }
934
935         int ret = 0;
936         ret = sttd_engine_setting_get_profanity_filter(value);
937         if (0 != ret) {
938                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get profanity filter : result(%d)", ret); 
939                 return ret;
940         }       
941
942         return STTD_ERROR_NONE;
943 }
944
945 int sttd_server_setting_set_profanity_filter(int pid, bool value)
946 {
947         /* check whether pid is valid */
948         if (true != sttd_setting_client_is(pid)) {
949                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
950                 return STTD_ERROR_INVALID_PARAMETER;
951         }
952
953         int ret = 0;
954         ret = sttd_engine_setting_set_profanity_filter(value);
955         if (0 != ret) {
956                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set profanity filter: result(%d)", ret); 
957                 return ret;
958         }       
959
960         return STTD_ERROR_NONE;
961 }
962
963 int sttd_server_setting_get_punctuation_override(int pid, bool* value)
964 {
965         /* check whether pid is valid */
966         if (true != sttd_setting_client_is(pid)) {
967                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
968                 return STTD_ERROR_INVALID_PARAMETER;
969         }
970
971         if (NULL == value) {
972                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
973                 return STTD_ERROR_INVALID_PARAMETER;
974         }
975
976         int ret = 0;
977         ret = sttd_engine_setting_get_punctuation_override(value);
978         if (0 != ret) {
979                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get punctuation override : result(%d)", ret); 
980                 return ret;
981         }       
982
983         return STTD_ERROR_NONE;
984 }
985
986 int sttd_server_setting_set_punctuation_override(int pid, bool value)
987 {
988         /* check whether pid is valid */
989         if (true != sttd_setting_client_is(pid)) {
990                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
991                 return STTD_ERROR_INVALID_PARAMETER;
992         }
993
994         int ret = 0;
995         ret = sttd_engine_setting_set_punctuation_override(value);
996         if (0 != ret) {
997                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set punctuation override : result(%d)", ret); 
998                 return ret;
999         }       
1000
1001         return STTD_ERROR_NONE;
1002 }
1003
1004 int sttd_server_setting_get_silence_detection(int pid, bool* value)
1005 {
1006         /* check whether pid is valid */
1007         if (true != sttd_setting_client_is(pid)) {
1008                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
1009                 return STTD_ERROR_INVALID_PARAMETER;
1010         }
1011
1012         if (NULL == value) {
1013                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
1014                 return STTD_ERROR_INVALID_PARAMETER;
1015         }
1016
1017         int ret = 0;
1018         ret = sttd_engine_setting_get_silence_detection(value);
1019         if (0 != ret) {
1020                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get silence detection : result(%d)", ret); 
1021                 return ret;
1022         }       
1023
1024         return STTD_ERROR_NONE;
1025 }
1026
1027 int sttd_server_setting_set_silence_detection(int pid, bool value)
1028 {
1029         /* check whether pid is valid */
1030         if (true != sttd_setting_client_is(pid)) {
1031                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
1032                 return STTD_ERROR_INVALID_PARAMETER;
1033         }
1034
1035         int ret = 0;
1036         ret = sttd_engine_setting_set_silence_detection(value);
1037         if (0 != ret) {
1038                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret); 
1039                 return ret;
1040         }       
1041
1042         return STTD_ERROR_NONE;
1043 }
1044
1045 int sttd_server_setting_get_engine_setting(int pid, char** engine_id, GList** lang_list)
1046 {       
1047         /* check whether pid is valid */
1048         if (true != sttd_setting_client_is(pid)) {
1049                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
1050                 return STTD_ERROR_INVALID_PARAMETER;
1051         }
1052
1053         if (0 != sttd_engine_setting_get_engine_setting_info(engine_id, lang_list)) {
1054                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine setting info"); 
1055                 return STTD_ERROR_OPERATION_FAILED;
1056         }
1057
1058         return STTD_ERROR_NONE;
1059 }
1060
1061 int sttd_server_setting_set_engine_setting(int pid, const char* key, const char* value)
1062 {       
1063         /* check whether pid is valid */
1064         if (true != sttd_setting_client_is(pid)) {
1065                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
1066                 return STTD_ERROR_INVALID_PARAMETER;
1067         }
1068
1069         if (0 != sttd_engine_setting_set_engine_setting(key, value)) {
1070                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine setting info"); 
1071                 return STTD_ERROR_OPERATION_FAILED;
1072         }
1073
1074         return STTD_ERROR_NONE;
1075 }