tizen beta release
[platform/core/uifw/stt.git] / client / stt.c
1 /*
2 * Copyright (c) 2011 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 <sys/wait.h>
16 #include <sys/types.h> 
17 #include <unistd.h>
18
19 #include "stt.h"
20 #include "stt_main.h"
21 #include "stt_client.h"
22 #include "stt_dbus.h"
23
24 #define CONNECTION_RETRY_COUNT 3
25
26 int __check_stt_daemon();
27
28 int stt_create(stt_h* stt)
29 {
30         int ret = 0; 
31
32         SLOG(LOG_DEBUG, TAG_STTC, "===== Create STT");
33
34         if (NULL == stt) {
35                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is null");
36                 return STT_ERROR_INVALID_PARAMETER;
37         }
38
39         /* check stt-daemon. */
40         __check_stt_daemon();   
41
42         if (0 == stt_client_get_size()) {
43                 if (0 != stt_dbus_open_connection()) {
44                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to open connection\n ");
45                         return STT_ERROR_OPERATION_FAILED;
46                 }
47         }
48
49         if (0 != stt_client_new(stt)) {
50                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client!!!!!");
51                 return STT_ERROR_OUT_OF_MEMORY;
52         }
53
54         /* request initialization */
55         int i = 0;
56         while (1) {
57                 ret = stt_dbus_request_initialize((*stt)->handle);
58                 
59                 if (STT_ERROR_ENGINE_NOT_FOUND == ret) {
60                         stt_client_destroy(*stt);
61                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : STT Engine Not founded");
62                         return ret;
63                 } else if(0 != ret) {
64                         sleep(1);
65                         if(CONNECTION_RETRY_COUNT == i) {
66                                 stt_client_destroy(*stt);
67                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : TIMED OUT");
68                                 return STT_ERROR_TIMED_OUT;                         
69                         }    
70                         i++;
71                 } else {
72                         /* success to connect stt-daemon */
73                         break;
74                 }
75         }
76
77         SLOG(LOG_DEBUG, TAG_STTC, "[Success] uid(%d)", (*stt)->handle);
78         
79         SLOG(LOG_DEBUG, TAG_STTC, "=====");
80         SLOG(LOG_DEBUG, TAG_STTC, " ");
81
82         return STT_ERROR_NONE;
83 }
84
85 int stt_destroy(stt_h stt)
86 {
87         SLOG(LOG_DEBUG, TAG_STTC, "===== Destroy STT");
88
89         if (NULL == stt) {
90                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
91                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
92                 SLOG(LOG_DEBUG, TAG_STTC, " ");
93                 return STT_ERROR_INVALID_PARAMETER;
94         }
95         
96         stt_client_s* client = stt_client_get(stt);
97
98         /* check handle */
99         if (NULL == client) {
100                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
101                 return STT_ERROR_INVALID_PARAMETER;
102         }
103         
104         int ret = stt_dbus_request_finalize(client->uid);
105         if (0 != ret) {
106                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize");
107         }
108         
109         /* Free resources */
110         stt_client_destroy(stt);
111
112         SLOG(LOG_DEBUG, TAG_STTC, "Success: destroy");
113
114         if (0 == stt_client_get_size()) {
115                 if (0 != stt_dbus_close_connection()) {
116                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to close connection\n ");
117                 }
118         }
119
120         SLOG(LOG_DEBUG, TAG_STTC, "=====");
121         SLOG(LOG_DEBUG, TAG_STTC, " ");
122
123         return STT_ERROR_NONE;
124 }
125
126 int stt_foreach_supported_languages(stt_h stt, stt_supported_language_cb callback, void* user_data)
127 {
128         SLOG(LOG_DEBUG, TAG_STTC, "===== Foreach Supported Language");
129
130         if (NULL == stt || NULL == callback) {
131                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
132                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
133                 SLOG(LOG_DEBUG, TAG_STTC, " ");
134                 return STT_ERROR_INVALID_PARAMETER;
135         }
136
137         stt_client_s* client = stt_client_get(stt);
138
139         /* check handle */
140         if (NULL == client) {
141                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
142                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
143                 SLOG(LOG_DEBUG, TAG_STTC, " ");
144                 return STT_ERROR_INVALID_PARAMETER;
145         }
146
147         int ret = 0;
148         ret = stt_dbus_request_get_support_langs(client->uid, client->stt, callback, user_data);
149         if (0 != ret) {
150                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages");
151         } else {
152                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
153         }
154
155         SLOG(LOG_DEBUG, TAG_STTC, "=====");
156         SLOG(LOG_DEBUG, TAG_STTC, " ");
157
158         return STT_ERROR_NONE;
159 }
160
161
162 int stt_get_default_language(stt_h stt, char** language)
163 {
164         SLOG(LOG_DEBUG, TAG_STTC, "===== Get Default Language");
165
166         if (NULL == stt || NULL == language) {
167                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
168                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
169                 SLOG(LOG_DEBUG, TAG_STTC, " ");
170                 return STT_ERROR_INVALID_PARAMETER;
171         }
172
173         stt_client_s* client = stt_client_get(stt);
174
175         /* check handle */
176         if (NULL == client) {
177                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
178                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
179                 SLOG(LOG_DEBUG, TAG_STTC, " ");
180                 return STT_ERROR_INVALID_PARAMETER;
181         }
182
183         int ret = 0;
184         ret = stt_dbus_request_get_default_lang(client->uid, language);
185
186         if (0 != ret) {
187                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail : request get default language");
188         } else {
189                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
190         }
191
192         SLOG(LOG_DEBUG, TAG_STTC, "=====");
193         SLOG(LOG_DEBUG, TAG_STTC, " ");
194
195         return ret;
196 }
197
198 int stt_get_state(stt_h stt, stt_state_e* state)
199 {
200         if (NULL == stt || NULL == state) {
201                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
202                 return STT_ERROR_INVALID_PARAMETER;
203         }
204
205         stt_client_s* client = stt_client_get(stt);
206
207         if (NULL == client) {
208                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
209                 return STT_ERROR_INVALID_PARAMETER;
210         }
211
212         *state = client->current_state;
213
214         switch(*state) {
215                 case STT_STATE_READY:           SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'");          break;
216                 case STT_STATE_RECORDING:       SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'");      break;
217                 case STT_STATE_PROCESSING:      SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'");     break;
218         }
219
220         return STT_ERROR_NONE;
221 }
222
223 int stt_is_partial_result_supported(stt_h stt, bool* partial_result)
224 {
225         if (NULL == stt || NULL == partial_result) {
226                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
227                 return STT_ERROR_INVALID_PARAMETER;
228         }
229
230         stt_client_s* client = stt_client_get(stt);
231
232         if (NULL == client) {
233                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not valid");
234                 return STT_ERROR_INVALID_PARAMETER;
235         }
236
237         int ret = 0;
238         ret = stt_dbus_request_is_partial_result_supported(client->uid, partial_result);
239
240         if (0 != ret) {
241                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get partial result supported");
242         } else {
243                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Partial result supporting is %s", *partial_result ? "true " : "false");
244         }
245
246         return STT_ERROR_NONE;
247 }
248
249 int stt_set_profanity_filter(stt_h stt, stt_option_profanity_e type)
250 {
251         if (NULL == stt) {
252                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
253                 return STT_ERROR_INVALID_PARAMETER;
254         }
255
256         stt_client_s* client = stt_client_get(stt);
257
258         if (NULL == client) {
259                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
260                 return STT_ERROR_INVALID_PARAMETER;
261         }
262
263         if (type >= STT_OPTION_PROFANITY_FALSE && type <= STT_OPTION_PROFANITY_AUTO)
264                 client->profanity = type;       
265         else {
266                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
267                 return STT_ERROR_INVALID_PARAMETER;
268         }
269
270         return STT_ERROR_NONE;
271 }
272
273 int stt_set_punctuation_override(stt_h stt, stt_option_punctuation_e type)
274 {
275         if (NULL == stt) {
276                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
277                 return STT_ERROR_INVALID_PARAMETER;
278         }
279
280         stt_client_s* client = stt_client_get(stt);
281
282         if (NULL == client) {
283                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
284                 return STT_ERROR_INVALID_PARAMETER;
285         }
286         
287         if (type >= STT_OPTION_PUNCTUATION_FALSE && type <= STT_OPTION_PUNCTUATION_AUTO)
288                 client->punctuation = type;     
289         else {
290                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
291                 return STT_ERROR_INVALID_PARAMETER;
292         }
293
294         return STT_ERROR_NONE;
295 }
296
297 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
298 {
299         if (NULL == stt) {
300                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
301                 return STT_ERROR_INVALID_PARAMETER;
302         }
303
304         stt_client_s* client = stt_client_get(stt);
305
306         if (NULL == client) {
307                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
308                 return STT_ERROR_INVALID_PARAMETER;
309         }
310
311         if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO)
312                 client->silence = type; 
313         else {
314                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
315                 return STT_ERROR_INVALID_PARAMETER;
316         }
317
318         return STT_ERROR_NONE;
319 }
320
321 int stt_start(stt_h stt, const char* language, const char* type)
322 {
323         SLOG(LOG_DEBUG, TAG_STTC, "===== STT START");
324
325         if (NULL == stt) {
326                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
327                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
328                 SLOG(LOG_DEBUG, TAG_STTC, " ");
329                 return STT_ERROR_INVALID_PARAMETER;
330         }
331
332         stt_client_s* client = stt_client_get(stt);
333
334         /* check handle */
335         if (NULL == client) {
336                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
337                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
338                 SLOG(LOG_DEBUG, TAG_STTC, " ");
339                 return STT_ERROR_INVALID_PARAMETER;
340         }
341
342         /* check state */
343         if (client->current_state != STT_STATE_READY) {
344                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY"); 
345                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
346                 SLOG(LOG_DEBUG, TAG_STTC, " ");
347                 return STT_ERROR_INVALID_STATE;
348         }
349
350         char* temp;
351         if (NULL == language) {
352                 temp = strdup("default");
353         } else {
354                 temp = strdup(language);
355         }
356
357         int ret; 
358         /* do request */
359         ret = stt_dbus_request_start(client->uid, temp, type, client->profanity, client->punctuation, client->silence);
360
361         if (ret) {
362                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start");
363         } else {
364                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
365
366                 if (NULL != client->state_changed_cb) {
367                         client->state_changed_cb(client->stt, client->current_state, STT_STATE_RECORDING, client->state_changed_user_data); 
368                         SLOG(LOG_DEBUG, TAG_STTC, "Called state changed : STT_STATE_RECORDING");
369                 } else {
370                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Don't register state changed callback");
371                 }    
372
373                 client->current_state = STT_STATE_RECORDING;
374         }
375
376         free(temp);
377
378         SLOG(LOG_DEBUG, TAG_STTC, "=====");
379         SLOG(LOG_DEBUG, TAG_STTC, " ");
380
381         return ret;
382 }
383
384 int stt_stop(stt_h stt)
385 {
386         SLOG(LOG_DEBUG, TAG_STTC, "===== STT STOP");
387
388         if (NULL == stt) {
389                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] [ERROR] Input parameter is NULL");
390                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
391                 SLOG(LOG_DEBUG, TAG_STTC, " ");
392                 return STT_ERROR_INVALID_PARAMETER;
393         }
394
395         stt_client_s* client = stt_client_get(stt);
396
397         /* check handle */
398         if (NULL == client) {
399                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
400                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
401                 SLOG(LOG_DEBUG, TAG_STTC, " ");
402                 return STT_ERROR_INVALID_PARAMETER;
403         }   
404         
405         /* check state */
406         if (client->current_state != STT_STATE_RECORDING) {
407                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state is NOT RECORDING"); 
408                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
409                 SLOG(LOG_DEBUG, TAG_STTC, " ");
410                 return STT_ERROR_INVALID_STATE;
411         }
412
413         int ret = 0; 
414         /* do request */
415         ret = stt_dbus_request_stop(client->uid);
416         if (0 != ret) {
417                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Fail to stop");
418         } else {
419                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
420
421                 if (NULL != client->state_changed_cb) {
422                         client->state_changed_cb(client->stt, client->current_state, STT_STATE_PROCESSING, client->state_changed_user_data); 
423                         SLOG(LOG_DEBUG, TAG_STTC, "Called state changed : STT_STATE_PROCESSING");
424                 } else {
425                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Don't register state changed callback");
426                 }
427
428                 client->current_state = STT_STATE_PROCESSING;
429         }
430
431         SLOG(LOG_DEBUG, TAG_STTC, "=====");
432         SLOG(LOG_DEBUG, TAG_STTC, " ");
433
434         return ret;
435 }
436
437
438 int stt_cancel(stt_h stt)
439 {
440         SLOG(LOG_DEBUG, TAG_STTC, "===== STT CANCEL");
441
442         if (NULL == stt) {
443                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
444                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
445                 SLOG(LOG_DEBUG, TAG_STTC, " ");
446                 return STT_ERROR_INVALID_PARAMETER;
447         }
448
449         stt_client_s* client = stt_client_get(stt);
450
451         /* check handle */
452         if (NULL == client) {
453                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
454                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
455                 SLOG(LOG_DEBUG, TAG_STTC, " ");
456                 return STT_ERROR_INVALID_PARAMETER;
457         }       
458
459         /* check state */
460         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
461                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : Current state is 'Ready'");
462                 SLOG(LOG_DEBUG, TAG_STTC, "=====");
463                 SLOG(LOG_DEBUG, TAG_STTC, " ");
464                 return STT_ERROR_INVALID_STATE;
465         }
466
467         int ret; 
468         /* do request */
469         ret = stt_dbus_request_cancel(client->uid);
470         if (0 != ret) {
471                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Fail to cancel");
472         } else {
473                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
474                 if (NULL != client->state_changed_cb) {
475                         client->state_changed_cb(client->stt, client->current_state, STT_STATE_READY, client->state_changed_user_data); 
476                         SLOG(LOG_DEBUG, TAG_STTC, "Called state changed : STT_STATE_READY");
477                 } else {
478                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Don't register state changed callback");
479                 }
480
481                 client->current_state = STT_STATE_READY;
482         }
483
484         SLOG(LOG_DEBUG, TAG_STTC, "=====");
485         SLOG(LOG_DEBUG, TAG_STTC, " ");
486
487         return ret;
488 }
489
490 int stt_get_recording_volume(stt_h stt, float* volume)
491 {
492         if (NULL == stt || NULL == volume) {
493                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
494                 return STT_ERROR_INVALID_PARAMETER;
495         }
496
497         stt_client_s* client = stt_client_get(stt);
498
499         /* check handle */
500         if (NULL == client) {
501                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
502                 return STT_ERROR_INVALID_PARAMETER;
503         } 
504         
505         if (STT_STATE_RECORDING != client->current_state) {
506                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state");
507                 return STT_ERROR_INVALID_STATE;
508         }    
509         
510         int ret = 0; 
511         ret = stt_dbus_request_get_audio_volume(client->uid, volume);
512         if (ret) {
513                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get audio volume");
514                 return ret;
515         }    
516
517         return STT_ERROR_NONE;
518 }
519
520 int __stt_cb_error(int uid, int reason)
521 {
522         stt_client_s* client = stt_client_get_by_uid(uid);
523         if( NULL == client ) {
524                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found\n");
525                 return -1;
526         }
527
528         client->current_state = STT_STATE_READY;
529
530         if (NULL != client->error_cb) {
531                 stt_client_use_callback(client);
532                 client->error_cb(client->stt, reason, client->error_user_data); 
533                 stt_client_not_use_callback(client);
534                 SLOG(LOG_DEBUG, TAG_STTC, "client error callback called");
535         } else {
536                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Error occur but user callback is null");
537         }    
538
539         return 0;
540 }
541
542 int __stt_cb_result(int uid, const char* type, const char** data, int data_count, const char* msg)
543 {
544         stt_client_s* client = NULL;
545         
546         client = stt_client_get_by_uid(uid);
547         if (NULL == client) {
548                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
549                 return -1;
550         }
551
552         SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result Message = %s", msg);
553
554         int i=0;
555         for (i = 0;i < data_count;i++) {
556                 if(NULL != data[i])
557                         SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
558         }       
559
560         if (NULL != client->result_cb) {
561                 stt_client_use_callback(client);
562                 client->result_cb(client->stt, type, data, data_count, msg, client->result_user_data);
563                 stt_client_not_use_callback(client);
564                 SLOG(LOG_DEBUG, TAG_STTC, "client result callback called");
565         } else {
566                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
567         }   
568
569         if (NULL != client->state_changed_cb) {
570                 client->state_changed_cb(client->stt, client->current_state, STT_STATE_READY, client->state_changed_user_data); 
571                 SLOG(LOG_DEBUG, TAG_STTC, "client state changed callback called");
572         } else {
573                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Don't register result callback");
574         }
575
576         client->current_state = STT_STATE_READY;
577
578         return 0;
579 }
580
581 int __stt_cb_partial_result(int uid, const char* data)
582 {
583         stt_client_s* client = NULL;
584
585         client = stt_client_get_by_uid(uid);
586         if (NULL == client) {
587                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
588                 return -1;
589         }
590
591         if (client->current_state == STT_STATE_READY) {
592                 SLOG(LOG_ERROR, TAG_STTC, "Current state has already been 'Ready' state");      
593                 return 0;
594         }
595
596         if (client->partial_result_cb) {
597                 stt_client_use_callback(client);
598                 client->partial_result_cb(client->stt, data, client->partial_result_user_data);
599                 stt_client_not_use_callback(client);
600                 SLOG(LOG_DEBUG, TAG_STTC, "client partial result callback called");
601         } else {
602                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Don't register partial result callback");
603         }   
604
605         return 0;
606 }
607
608 int __stt_cb_stop_by_daemon(int uid)
609 {
610         stt_client_s* client = stt_client_get_by_uid(uid);
611         if( NULL == client ) {
612                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found\n");
613                 return -1;
614         }
615
616         if (client->current_state != STT_STATE_RECORDING) {
617                 SLOG(LOG_ERROR, TAG_STTC, "Current state is NOT 'Recording' state");    
618                 return 0;
619         }
620
621         if (NULL != client->state_changed_cb) {
622                 stt_client_use_callback(client);
623                 client->state_changed_cb(client->stt, client->current_state, STT_STATE_PROCESSING, client->state_changed_user_data); 
624                 stt_client_not_use_callback(client);
625                 SLOG(LOG_DEBUG, TAG_STTC, "client state changed callback called");
626         } else {
627                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Error occur but user callback is null");
628         }
629
630         client->current_state = STT_STATE_PROCESSING;
631
632         return 0;
633 }
634
635 int stt_set_result_cb(stt_h stt, stt_result_cb callback, void* user_data)
636 {
637         if (stt == NULL || callback == NULL)
638                 return STT_ERROR_INVALID_PARAMETER;
639
640         stt_client_s* client = stt_client_get(stt);
641
642         /* check handle */
643         if (NULL == client) {
644                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
645                 return STT_ERROR_INVALID_PARAMETER;
646         }
647
648         if (STT_STATE_READY != client->current_state) {
649                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
650                 return STT_ERROR_INVALID_STATE;
651         }
652
653         client->result_cb = callback;
654         client->result_user_data = user_data;
655
656         return 0;
657 }
658
659 int stt_unset_result_cb(stt_h stt)
660 {
661         if (NULL == stt)
662                 return STT_ERROR_INVALID_PARAMETER;
663
664         stt_client_s* client = stt_client_get(stt);
665
666         /* check handle */
667         if (NULL == client) {
668                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
669                 return STT_ERROR_INVALID_PARAMETER;
670         }
671
672         if (STT_STATE_READY != client->current_state) {
673                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
674                 return STT_ERROR_INVALID_STATE;
675         }
676
677         client->result_cb = NULL;
678         client->result_user_data = NULL;
679
680         return 0;
681 }
682
683 int stt_set_partial_result_cb(stt_h stt, stt_partial_result_cb callback, void* user_data)
684 {
685         if (NULL == stt || NULL == callback)
686                 return STT_ERROR_INVALID_PARAMETER;
687
688         stt_client_s* client = stt_client_get(stt);
689
690         /* check handle */
691         if (NULL == client) {
692                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
693                 return STT_ERROR_INVALID_PARAMETER;
694         }
695
696         if (STT_STATE_READY != client->current_state) {
697                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
698                 return STT_ERROR_INVALID_STATE;
699         }
700
701         client->partial_result_cb = callback;
702         client->partial_result_user_data = user_data;
703
704         return 0;
705 }
706
707 int stt_unset_partial_result_cb(stt_h stt)
708 {
709         if (NULL == stt)
710                 return STT_ERROR_INVALID_PARAMETER;
711
712         stt_client_s* client = stt_client_get(stt);
713
714         /* check handle */
715         if (NULL == client) {
716                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
717                 return STT_ERROR_INVALID_PARAMETER;
718         }
719
720         if (STT_STATE_READY != client->current_state) {
721                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
722                 return STT_ERROR_INVALID_STATE;
723         }
724
725         client->partial_result_cb = NULL;
726         client->partial_result_user_data = NULL;
727
728         return 0;
729 }
730
731 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
732 {
733         if (NULL == stt || NULL == callback)
734                 return STT_ERROR_INVALID_PARAMETER;
735
736         stt_client_s* client = stt_client_get(stt);
737
738         /* check handle */
739         if (NULL == client) {
740                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
741                 return STT_ERROR_INVALID_PARAMETER;
742         }
743
744         if (STT_STATE_READY != client->current_state) {
745                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
746                 return STT_ERROR_INVALID_STATE;
747         }
748
749         client->state_changed_cb = callback;
750         client->state_changed_user_data = user_data;
751
752         return 0;
753 }
754
755 int stt_unset_state_changed_cb(stt_h stt)
756 {
757         if (NULL == stt)
758                 return STT_ERROR_INVALID_PARAMETER;
759
760         stt_client_s* client = stt_client_get(stt);
761
762         /* check handle */
763         if (NULL == client) {
764                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
765                 return STT_ERROR_INVALID_PARAMETER;
766         }
767
768         if (STT_STATE_READY != client->current_state) {
769                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
770                 return STT_ERROR_INVALID_STATE;
771         }
772
773         client->state_changed_cb = NULL;
774         client->state_changed_user_data = NULL;
775
776         return 0;
777 }
778
779
780 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
781 {
782         if (NULL == stt || NULL == callback)
783                 return STT_ERROR_INVALID_PARAMETER;
784
785         stt_client_s* client = stt_client_get(stt);
786
787         /* check handle */
788         if (NULL == client) {
789                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
790                 return STT_ERROR_INVALID_PARAMETER;
791         }
792
793         if (STT_STATE_READY != client->current_state) {
794                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
795                 return STT_ERROR_INVALID_STATE;
796         }
797
798         client->error_cb = callback;
799         client->error_user_data = user_data;
800
801         return 0;
802 }
803
804 int stt_unset_error_cb(stt_h stt)
805 {
806         if (NULL == stt)
807                 return STT_ERROR_INVALID_PARAMETER;
808
809         stt_client_s* client = stt_client_get(stt);
810
811         /* check handle */
812         if (NULL == client) {
813                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
814                 return STT_ERROR_INVALID_PARAMETER;
815         }
816
817         if (STT_STATE_READY != client->current_state) {
818                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'."); 
819                 return STT_ERROR_INVALID_STATE;
820         }
821
822         client->error_cb = NULL;
823         client->error_user_data = NULL;
824
825         return 0;
826 }
827
828 static bool __stt_is_alive()
829 {
830         FILE *fp = NULL;
831         char buff[256];
832         char cmd[256];
833         int i=0;
834
835         memset(buff, '\0', 256);
836         memset(cmd, '\0', 256);
837
838         if ((fp = popen("ps -eo \"cmd\"", "r")) == NULL) {
839                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] popen error \n");
840                 return FALSE;
841         }
842
843         while(fgets(buff, 255, fp)) {
844                 if (i == 0) {
845                         i++;
846                         continue;
847                 }
848
849                 sscanf(buff, "%s", cmd);
850
851                 if( 0 == strncmp(cmd, "[stt-daemon]", strlen("[stt-daemon]")) ||
852                         0 == strncmp(cmd, "stt-daemon", strlen("stt-daemon")) ||
853                         0 == strncmp(cmd, "/usr/bin/stt-daemon", strlen("/usr/bin/stt-daemon"))
854                         ) {
855                         fclose(fp);
856                         return TRUE;
857                 }
858                 i++;
859         }
860         fclose(fp);
861
862         return FALSE;
863 }
864
865 static void __my_sig_child(int signo, siginfo_t *info, void *data)
866 {
867         int status;
868         pid_t child_pid, child_pgid;
869
870         child_pgid = getpgid(info->si_pid);
871         SLOG(LOG_DEBUG, TAG_STTC, "Signal handler: dead pid = %d, pgid = %d\n", info->si_pid, child_pgid);
872
873         while((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
874                 if(child_pid == child_pgid)
875                         killpg(child_pgid, SIGKILL);
876         }
877
878         return;
879 }
880
881
882 int __check_stt_daemon()
883 {
884         if( TRUE == __stt_is_alive() )
885                 return 0;
886         
887         /* fork-exec stt-daemon */
888         SLOG(LOG_DEBUG, TAG_STTC, "THERE IS NO stt-daemon \n");
889
890         int pid, i;
891         struct sigaction act, dummy;
892
893         act.sa_handler = NULL;
894         act.sa_sigaction = __my_sig_child;
895         sigemptyset(&act.sa_mask);
896         act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
897                 
898         if(sigaction(SIGCHLD, &act, &dummy) < 0) {
899                 SLOG(LOG_DEBUG, TAG_STTC, "%s\n", "Cannot make a signal handler\n");
900                 return -1;
901         }
902
903         pid = fork();
904
905         switch(pid) {
906         case -1:
907                 SLOG(LOG_DEBUG, TAG_STTC, "[STT ERROR] fail to create STT-DAEMON \n");
908                 break;
909
910         case 0:
911                 setsid();
912                 for (i = 0;i < _NSIG;i++)
913                         signal(i, SIG_DFL);
914
915                 execl("/usr/bin/stt-daemon", "/usr/bin/stt-daemon", NULL);
916                 break;
917
918         default:
919                 sleep(1);
920                 break;
921         }
922
923         return 0;
924 }
925
926
927
928