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