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.
16 #include <sys/types.h>
24 #include "stt_client.h"
27 #define CONNECTION_RETRY_COUNT 3
29 static bool g_is_daemon_started = false;
31 static int __check_stt_daemon();
32 static Eina_Bool __stt_notify_state_changed(void *data);
33 static Eina_Bool __stt_notify_error(void *data);
35 int stt_create(stt_h* stt)
37 SLOG(LOG_DEBUG, TAG_STTC, "===== Create STT");
40 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is null");
41 return STT_ERROR_INVALID_PARAMETER;
44 if (0 == stt_client_get_size()) {
45 if (0 != stt_dbus_open_connection()) {
46 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to open connection");
47 return STT_ERROR_OPERATION_FAILED;
51 if (0 != stt_client_new(stt)) {
52 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client!");
53 return STT_ERROR_OUT_OF_MEMORY;
56 SLOG(LOG_DEBUG, TAG_STTC, "[Success] uid(%d)", (*stt)->handle);
58 SLOG(LOG_DEBUG, TAG_STTC, "=====");
59 SLOG(LOG_DEBUG, TAG_STTC, " ");
61 return STT_ERROR_NONE;
64 int stt_destroy(stt_h stt)
66 SLOG(LOG_DEBUG, TAG_STTC, "===== Destroy STT");
69 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
70 SLOG(LOG_DEBUG, TAG_STTC, "=====");
71 SLOG(LOG_DEBUG, TAG_STTC, " ");
72 return STT_ERROR_INVALID_PARAMETER;
75 stt_client_s* client = stt_client_get(stt);
79 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
80 return STT_ERROR_INVALID_PARAMETER;
86 switch (client->current_state) {
87 case STT_STATE_PROCESSING:
88 case STT_STATE_RECORDING:
90 ret = stt_dbus_request_finalize(client->uid);
92 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize");
94 case STT_STATE_CREATED:
96 stt_client_destroy(stt);
100 SLOG(LOG_DEBUG, TAG_STTC, "Success: destroy");
102 if (0 == stt_client_get_size()) {
103 if (0 != stt_dbus_close_connection()) {
104 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to close connection");
108 SLOG(LOG_DEBUG, TAG_STTC, "=====");
109 SLOG(LOG_DEBUG, TAG_STTC, " ");
111 return STT_ERROR_NONE;
114 static Eina_Bool __stt_connect_daemon(void *data)
116 SLOG(LOG_DEBUG, TAG_STTC, "===== Connect daemon");
118 stt_h stt = (stt_h)data;
120 stt_client_s* client = stt_client_get(stt);
122 if (NULL == client) {
123 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
124 SLOG(LOG_DEBUG, TAG_STTC, "=====");
125 SLOG(LOG_DEBUG, TAG_STTC, " ");
126 return STT_ERROR_INVALID_PARAMETER;
130 if (0 != stt_dbus_request_hello()) {
131 if (false == g_is_daemon_started) {
132 g_is_daemon_started = true;
133 __check_stt_daemon();
138 /* request initialization */
141 bool silence_supported = false;
142 bool profanity_supported = false;
143 bool punctuation_supported = false;
146 ret = stt_dbus_request_initialize(client->uid, &silence_supported, &profanity_supported, &punctuation_supported);
148 if (STT_ERROR_ENGINE_NOT_FOUND == ret) {
149 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : STT Engine Not found");
151 client->reason = STT_ERROR_ENGINE_NOT_FOUND;
153 ecore_timer_add(0, __stt_notify_error, (void*)stt);
157 } else if(0 != ret) {
159 if(CONNECTION_RETRY_COUNT == i) {
160 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : TIMED OUT");
162 client->reason = STT_ERROR_TIMED_OUT;
164 ecore_timer_add(0, __stt_notify_error, (void*)stt);
170 /* success to connect stt-daemon */
171 stt_client_set_option_supported(client->stt, silence_supported, profanity_supported, punctuation_supported);
172 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), profanity(%s), punctuation(%s)",
173 silence_supported ? "true" : "false", profanity_supported ? "true" : "false", punctuation_supported ? "true" : "false");
178 client->before_state = client->current_state;
179 client->current_state = STT_STATE_READY;
181 ecore_timer_add(0, __stt_notify_state_changed, (void*)stt);
183 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] uid(%d)", client->uid);
185 SLOG(LOG_DEBUG, TAG_STTC, "=====");
186 SLOG(LOG_DEBUG, TAG_STTC, " ");
192 int stt_prepare(stt_h stt)
194 SLOG(LOG_DEBUG, TAG_STTC, "===== Prepare STT");
196 stt_client_s* client = stt_client_get(stt);
199 if (NULL == client) {
200 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
201 SLOG(LOG_DEBUG, TAG_STTC, "=====");
202 SLOG(LOG_DEBUG, TAG_STTC, " ");
203 return STT_ERROR_INVALID_PARAMETER;
207 if (client->current_state != STT_STATE_CREATED) {
208 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not 'CREATED'");
209 SLOG(LOG_DEBUG, TAG_STTC, "=====");
210 SLOG(LOG_DEBUG, TAG_STTC, " ");
211 return STT_ERROR_INVALID_STATE;
214 ecore_timer_add(0, __stt_connect_daemon, (void*)stt);
216 SLOG(LOG_DEBUG, TAG_STTC, "=====");
217 SLOG(LOG_DEBUG, TAG_STTC, " ");
219 return STT_ERROR_NONE;
222 int stt_unprepare(stt_h stt)
224 SLOG(LOG_DEBUG, TAG_STTC, "===== Unprepare STT");
226 stt_client_s* client = stt_client_get(stt);
229 if (NULL == client) {
230 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
231 return STT_ERROR_INVALID_PARAMETER;
235 if (client->current_state != STT_STATE_READY) {
236 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not 'READY'");
237 SLOG(LOG_DEBUG, TAG_STTC, "=====");
238 SLOG(LOG_DEBUG, TAG_STTC, " ");
239 return STT_ERROR_INVALID_STATE;
242 int ret = stt_dbus_request_finalize(client->uid);
244 SLOG(LOG_WARN, TAG_STTC, "[ERROR] Fail to request finalize");
247 client->before_state = client->current_state;
248 client->current_state = STT_STATE_CREATED;
250 ecore_timer_add(0, __stt_notify_state_changed, (void*)stt);
252 SLOG(LOG_DEBUG, TAG_STTC, "=====");
253 SLOG(LOG_DEBUG, TAG_STTC, " ");
255 return STT_ERROR_NONE;
258 int stt_foreach_supported_languages(stt_h stt, stt_supported_language_cb callback, void* user_data)
260 SLOG(LOG_DEBUG, TAG_STTC, "===== Foreach Supported Language");
262 if (NULL == stt || NULL == callback) {
263 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
264 SLOG(LOG_DEBUG, TAG_STTC, "=====");
265 SLOG(LOG_DEBUG, TAG_STTC, " ");
266 return STT_ERROR_INVALID_PARAMETER;
269 stt_client_s* client = stt_client_get(stt);
272 if (NULL == client) {
273 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
274 SLOG(LOG_DEBUG, TAG_STTC, "=====");
275 SLOG(LOG_DEBUG, TAG_STTC, " ");
276 return STT_ERROR_INVALID_PARAMETER;
280 if (client->current_state != STT_STATE_READY) {
281 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
282 return STT_ERROR_INVALID_STATE;
286 ret = stt_dbus_request_get_support_langs(client->uid, client->stt, callback, user_data);
288 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages");
290 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
293 SLOG(LOG_DEBUG, TAG_STTC, "=====");
294 SLOG(LOG_DEBUG, TAG_STTC, " ");
296 return STT_ERROR_NONE;
300 int stt_get_default_language(stt_h stt, char** language)
302 SLOG(LOG_DEBUG, TAG_STTC, "===== Get Default Language");
304 if (NULL == stt || NULL == language) {
305 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
306 SLOG(LOG_DEBUG, TAG_STTC, "=====");
307 SLOG(LOG_DEBUG, TAG_STTC, " ");
308 return STT_ERROR_INVALID_PARAMETER;
311 stt_client_s* client = stt_client_get(stt);
314 if (NULL == client) {
315 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
316 SLOG(LOG_DEBUG, TAG_STTC, "=====");
317 SLOG(LOG_DEBUG, TAG_STTC, " ");
318 return STT_ERROR_INVALID_PARAMETER;
322 if (client->current_state != STT_STATE_READY) {
323 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
324 return STT_ERROR_INVALID_STATE;
328 ret = stt_dbus_request_get_default_lang(client->uid, language);
331 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail : request get default language");
333 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
336 SLOG(LOG_DEBUG, TAG_STTC, "=====");
337 SLOG(LOG_DEBUG, TAG_STTC, " ");
342 int stt_get_state(stt_h stt, stt_state_e* state)
344 if (NULL == stt || NULL == state) {
345 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
346 return STT_ERROR_INVALID_PARAMETER;
349 stt_client_s* client = stt_client_get(stt);
351 if (NULL == client) {
352 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
353 return STT_ERROR_INVALID_PARAMETER;
356 *state = client->current_state;
359 case STT_STATE_CREATED: SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'CREATED'"); break;
360 case STT_STATE_READY: SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'"); break;
361 case STT_STATE_RECORDING: SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'"); break;
362 case STT_STATE_PROCESSING: SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'"); break;
365 return STT_ERROR_NONE;
368 int stt_is_partial_result_supported(stt_h stt, bool* partial_result)
370 if (NULL == stt || NULL == partial_result) {
371 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
372 return STT_ERROR_INVALID_PARAMETER;
375 stt_client_s* client = stt_client_get(stt);
377 if (NULL == client) {
378 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not valid");
379 return STT_ERROR_INVALID_PARAMETER;
383 if (client->current_state != STT_STATE_READY) {
384 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
385 return STT_ERROR_INVALID_STATE;
389 ret = stt_dbus_request_is_partial_result_supported(client->uid, partial_result);
392 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get partial result supported");
394 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Partial result supporting is %s", *partial_result ? "true " : "false");
397 return STT_ERROR_NONE;
400 int stt_set_profanity_filter(stt_h stt, stt_option_profanity_e type)
403 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
404 return STT_ERROR_INVALID_PARAMETER;
407 stt_client_s* client = stt_client_get(stt);
409 if (NULL == client) {
410 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
411 return STT_ERROR_INVALID_PARAMETER;
415 if (client->current_state != STT_STATE_READY) {
416 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
417 return STT_ERROR_INVALID_STATE;
420 if (true == client->profanity_supported) {
421 if (type >= STT_OPTION_PROFANITY_FALSE && type <= STT_OPTION_PROFANITY_AUTO)
422 client->profanity = type;
424 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
425 return STT_ERROR_INVALID_PARAMETER;
428 return STT_ERROR_NOT_SUPPORTED_FEATURE;
431 return STT_ERROR_NONE;
434 int stt_set_punctuation_override(stt_h stt, stt_option_punctuation_e type)
437 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
438 return STT_ERROR_INVALID_PARAMETER;
441 stt_client_s* client = stt_client_get(stt);
443 if (NULL == client) {
444 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
445 return STT_ERROR_INVALID_PARAMETER;
449 if (client->current_state != STT_STATE_READY) {
450 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
451 return STT_ERROR_INVALID_STATE;
454 if (true == client->punctuation_supported) {
455 if (type >= STT_OPTION_PUNCTUATION_FALSE && type <= STT_OPTION_PUNCTUATION_AUTO)
456 client->punctuation = type;
458 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
459 return STT_ERROR_INVALID_PARAMETER;
462 return STT_ERROR_NOT_SUPPORTED_FEATURE;
465 return STT_ERROR_NONE;
468 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
471 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
472 return STT_ERROR_INVALID_PARAMETER;
475 stt_client_s* client = stt_client_get(stt);
477 if (NULL == client) {
478 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get state : A handle is not valid");
479 return STT_ERROR_INVALID_PARAMETER;
483 if (client->current_state != STT_STATE_READY) {
484 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
485 return STT_ERROR_INVALID_STATE;
488 if (true == client->silence_supported) {
489 if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO)
490 client->silence = type;
492 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
493 return STT_ERROR_INVALID_PARAMETER;
496 return STT_ERROR_NOT_SUPPORTED_FEATURE;
499 return STT_ERROR_NONE;
502 int stt_start(stt_h stt, const char* language, const char* type)
504 SLOG(LOG_DEBUG, TAG_STTC, "===== STT START");
507 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
508 SLOG(LOG_DEBUG, TAG_STTC, "=====");
509 SLOG(LOG_DEBUG, TAG_STTC, " ");
510 return STT_ERROR_INVALID_PARAMETER;
513 stt_client_s* client = stt_client_get(stt);
516 if (NULL == client) {
517 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
518 SLOG(LOG_DEBUG, TAG_STTC, "=====");
519 SLOG(LOG_DEBUG, TAG_STTC, " ");
520 return STT_ERROR_INVALID_PARAMETER;
524 if (client->current_state != STT_STATE_READY) {
525 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state is not READY");
526 SLOG(LOG_DEBUG, TAG_STTC, "=====");
527 SLOG(LOG_DEBUG, TAG_STTC, " ");
528 return STT_ERROR_INVALID_STATE;
532 if (NULL == language) {
533 temp = strdup("default");
535 temp = strdup(language);
540 ret = stt_dbus_request_start(client->uid, temp, type, client->profanity, client->punctuation, client->silence);
543 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start");
545 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
547 client->before_state = client->current_state;
548 client->current_state = STT_STATE_RECORDING;
550 ecore_timer_add(0, __stt_notify_state_changed, (void*)stt);
555 SLOG(LOG_DEBUG, TAG_STTC, "=====");
556 SLOG(LOG_DEBUG, TAG_STTC, " ");
561 int stt_stop(stt_h stt)
563 SLOG(LOG_DEBUG, TAG_STTC, "===== STT STOP");
566 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] [ERROR] Input parameter is NULL");
567 SLOG(LOG_DEBUG, TAG_STTC, "=====");
568 SLOG(LOG_DEBUG, TAG_STTC, " ");
569 return STT_ERROR_INVALID_PARAMETER;
572 stt_client_s* client = stt_client_get(stt);
575 if (NULL == client) {
576 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
577 SLOG(LOG_DEBUG, TAG_STTC, "=====");
578 SLOG(LOG_DEBUG, TAG_STTC, " ");
579 return STT_ERROR_INVALID_PARAMETER;
583 if (client->current_state != STT_STATE_RECORDING) {
584 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state is NOT RECORDING");
585 SLOG(LOG_DEBUG, TAG_STTC, "=====");
586 SLOG(LOG_DEBUG, TAG_STTC, " ");
587 return STT_ERROR_INVALID_STATE;
592 ret = stt_dbus_request_stop(client->uid);
594 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Fail to stop");
596 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
598 client->before_state = client->current_state;
599 client->current_state = STT_STATE_PROCESSING;
601 ecore_timer_add(0, __stt_notify_state_changed, (void*)stt);
604 SLOG(LOG_DEBUG, TAG_STTC, "=====");
605 SLOG(LOG_DEBUG, TAG_STTC, " ");
611 int stt_cancel(stt_h stt)
613 SLOG(LOG_DEBUG, TAG_STTC, "===== STT CANCEL");
616 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
617 SLOG(LOG_DEBUG, TAG_STTC, "=====");
618 SLOG(LOG_DEBUG, TAG_STTC, " ");
619 return STT_ERROR_INVALID_PARAMETER;
622 stt_client_s* client = stt_client_get(stt);
625 if (NULL == client) {
626 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
627 SLOG(LOG_DEBUG, TAG_STTC, "=====");
628 SLOG(LOG_DEBUG, TAG_STTC, " ");
629 return STT_ERROR_INVALID_PARAMETER;
633 if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
634 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : Current state is 'Ready'");
635 SLOG(LOG_DEBUG, TAG_STTC, "=====");
636 SLOG(LOG_DEBUG, TAG_STTC, " ");
637 return STT_ERROR_INVALID_STATE;
642 ret = stt_dbus_request_cancel(client->uid);
644 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Fail to cancel");
646 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
648 client->before_state = client->current_state;
649 client->current_state = STT_STATE_READY;
651 ecore_timer_add(0, __stt_notify_state_changed, (void*)stt);
654 SLOG(LOG_DEBUG, TAG_STTC, "=====");
655 SLOG(LOG_DEBUG, TAG_STTC, " ");
660 int stt_get_recording_volume(stt_h stt, float* volume)
662 if (NULL == stt || NULL == volume) {
663 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
664 return STT_ERROR_INVALID_PARAMETER;
667 stt_client_s* client = stt_client_get(stt);
670 if (NULL == client) {
671 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
672 return STT_ERROR_INVALID_PARAMETER;
675 if (STT_STATE_RECORDING != client->current_state) {
676 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state");
677 return STT_ERROR_INVALID_STATE;
681 ret = stt_dbus_request_get_audio_volume(client->uid, volume);
683 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get audio volume");
687 return STT_ERROR_NONE;
690 static Eina_Bool __stt_notify_error(void *data)
692 stt_h stt = (stt_h)data;
694 stt_client_s* client = stt_client_get(stt);
697 if (NULL == client) {
698 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
702 if (NULL != client->error_cb) {
703 stt_client_use_callback(client);
704 client->error_cb(client->stt, client->reason, client->error_user_data);
705 stt_client_not_use_callback(client);
706 SLOG(LOG_DEBUG, TAG_STTC, "Error callback is called");
708 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
714 int __stt_cb_error(int uid, int reason)
716 stt_client_s* client = stt_client_get_by_uid(uid);
717 if( NULL == client ) {
718 SLOG(LOG_ERROR, TAG_STTC, "Handle not found\n");
722 client->reason = reason;
724 if (NULL != client->error_cb) {
725 ecore_timer_add(0, __stt_notify_error, client->stt);
727 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
733 static Eina_Bool __stt_notify_result(void *data)
735 stt_h stt = (stt_h)data;
737 stt_client_s* client = stt_client_get(stt);
740 if (NULL == client) {
741 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
745 if (NULL != client->result_cb) {
746 stt_client_use_callback(client);
747 client->result_cb(client->stt, client->type, (const char**)client->data_list, client->data_count, client->msg, client->result_user_data);
748 stt_client_not_use_callback(client);
749 SLOG(LOG_DEBUG, TAG_STTC, "client result callback called");
751 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
755 if (NULL != client->type)
758 if (NULL != client->data_list) {
760 temp = client->data_list;
763 for (i = 0;i < client->data_count;i++) {
767 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
769 free(client->data_list);
772 if (NULL != client->msg)
775 client->data_count = 0;
780 static Eina_Bool __stt_notify_state_changed(void *data)
782 stt_h stt = (stt_h)data;
784 stt_client_s* client = stt_client_get(stt);
787 if (NULL == client) {
788 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
792 if (NULL != client->state_changed_cb) {
793 stt_client_use_callback(client);
794 client->state_changed_cb(client->stt, client->before_state, client->current_state, client->state_changed_user_data);
795 stt_client_not_use_callback(client);
796 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
798 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
804 int __stt_cb_result(int uid, const char* type, const char** data, int data_count, const char* msg)
806 stt_client_s* client = NULL;
808 client = stt_client_get_by_uid(uid);
809 if (NULL == client) {
810 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
814 SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result Message = %s", msg);
817 for (i = 0;i < data_count;i++) {
819 SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
822 if (NULL != client->result_cb) {
823 client->type = strdup(type);
824 client->msg = strdup(msg);
825 client->data_count = data_count;
827 if (data_count > 0) {
829 temp = malloc( sizeof(char*) * data_count);
831 for (i = 0;i < data_count;i++) {
833 temp[i] = strdup(data[i]);
835 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
838 client->data_list = temp;
841 ecore_timer_add(0, __stt_notify_result, client->stt);
843 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
846 client->before_state = client->current_state;
847 client->current_state = STT_STATE_READY;
849 if (NULL != client->state_changed_cb) {
850 ecore_timer_add(0, __stt_notify_state_changed, client->stt);
852 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
858 static Eina_Bool __stt_notify_partial_result(void *data)
860 stt_h stt = (stt_h)data;
862 stt_client_s* client = stt_client_get(stt);
865 if (NULL == client) {
866 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
870 if (client->partial_result_cb) {
871 stt_client_use_callback(client);
872 client->partial_result_cb(client->stt, client->partial_result, client->partial_result_user_data);
873 stt_client_not_use_callback(client);
874 SLOG(LOG_DEBUG, TAG_STTC, "Partial result callback is called");
876 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Partial result callback is null");
879 if (NULL != client->partial_result)
880 free(client->partial_result);
885 int __stt_cb_partial_result(int uid, const char* data)
887 stt_client_s* client = NULL;
889 client = stt_client_get_by_uid(uid);
890 if (NULL == client) {
891 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
895 if (client->current_state == STT_STATE_READY) {
896 SLOG(LOG_ERROR, TAG_STTC, "Current state has already been 'Ready' state");
900 if (client->partial_result_cb) {
901 client->partial_result = strdup(data);
902 ecore_timer_add(0, __stt_notify_partial_result, client->stt);
904 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Partial result callback is null");
910 int __stt_cb_set_state(int uid, int state)
912 stt_client_s* client = stt_client_get_by_uid(uid);
913 if( NULL == client ) {
914 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
918 stt_state_e state_from_daemon = (stt_state_e)state;
920 if (client->current_state == state_from_daemon) {
921 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
925 client->before_state = client->current_state;
926 client->current_state = state_from_daemon;
928 ecore_timer_add(0, __stt_notify_state_changed, client->stt);
932 int stt_set_result_cb(stt_h stt, stt_result_cb callback, void* user_data)
934 if (stt == NULL || callback == NULL)
935 return STT_ERROR_INVALID_PARAMETER;
937 stt_client_s* client = stt_client_get(stt);
940 if (NULL == client) {
941 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
942 return STT_ERROR_INVALID_PARAMETER;
945 if (STT_STATE_CREATED != client->current_state) {
946 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
947 return STT_ERROR_INVALID_STATE;
950 client->result_cb = callback;
951 client->result_user_data = user_data;
956 int stt_unset_result_cb(stt_h stt)
959 return STT_ERROR_INVALID_PARAMETER;
961 stt_client_s* client = stt_client_get(stt);
964 if (NULL == client) {
965 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
966 return STT_ERROR_INVALID_PARAMETER;
969 if (STT_STATE_CREATED != client->current_state) {
970 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
971 return STT_ERROR_INVALID_STATE;
974 client->result_cb = NULL;
975 client->result_user_data = NULL;
980 int stt_set_partial_result_cb(stt_h stt, stt_partial_result_cb callback, void* user_data)
982 if (NULL == stt || NULL == callback)
983 return STT_ERROR_INVALID_PARAMETER;
985 stt_client_s* client = stt_client_get(stt);
988 if (NULL == client) {
989 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
990 return STT_ERROR_INVALID_PARAMETER;
993 if (STT_STATE_CREATED != client->current_state) {
994 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
995 return STT_ERROR_INVALID_STATE;
998 client->partial_result_cb = callback;
999 client->partial_result_user_data = user_data;
1004 int stt_unset_partial_result_cb(stt_h stt)
1007 return STT_ERROR_INVALID_PARAMETER;
1009 stt_client_s* client = stt_client_get(stt);
1012 if (NULL == client) {
1013 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1014 return STT_ERROR_INVALID_PARAMETER;
1017 if (STT_STATE_CREATED != client->current_state) {
1018 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
1019 return STT_ERROR_INVALID_STATE;
1022 client->partial_result_cb = NULL;
1023 client->partial_result_user_data = NULL;
1028 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
1030 if (NULL == stt || NULL == callback)
1031 return STT_ERROR_INVALID_PARAMETER;
1033 stt_client_s* client = stt_client_get(stt);
1036 if (NULL == client) {
1037 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1038 return STT_ERROR_INVALID_PARAMETER;
1041 if (STT_STATE_CREATED != client->current_state) {
1042 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
1043 return STT_ERROR_INVALID_STATE;
1046 client->state_changed_cb = callback;
1047 client->state_changed_user_data = user_data;
1052 int stt_unset_state_changed_cb(stt_h stt)
1055 return STT_ERROR_INVALID_PARAMETER;
1057 stt_client_s* client = stt_client_get(stt);
1060 if (NULL == client) {
1061 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1062 return STT_ERROR_INVALID_PARAMETER;
1065 if (STT_STATE_CREATED != client->current_state) {
1066 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
1067 return STT_ERROR_INVALID_STATE;
1070 client->state_changed_cb = NULL;
1071 client->state_changed_user_data = NULL;
1077 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
1079 if (NULL == stt || NULL == callback)
1080 return STT_ERROR_INVALID_PARAMETER;
1082 stt_client_s* client = stt_client_get(stt);
1085 if (NULL == client) {
1086 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1087 return STT_ERROR_INVALID_PARAMETER;
1090 if (STT_STATE_CREATED != client->current_state) {
1091 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
1092 return STT_ERROR_INVALID_STATE;
1095 client->error_cb = callback;
1096 client->error_user_data = user_data;
1101 int stt_unset_error_cb(stt_h stt)
1104 return STT_ERROR_INVALID_PARAMETER;
1106 stt_client_s* client = stt_client_get(stt);
1109 if (NULL == client) {
1110 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1111 return STT_ERROR_INVALID_PARAMETER;
1114 if (STT_STATE_CREATED != client->current_state) {
1115 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state is not 'ready'.");
1116 return STT_ERROR_INVALID_STATE;
1119 client->error_cb = NULL;
1120 client->error_user_data = NULL;
1125 int __get_cmd_line(char *file, char *buf)
1130 fp = fopen(file, "r");
1132 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Get command line");
1136 memset(buf, 0, 256);
1137 fgets(buf, 256, fp);
1143 static bool __stt_is_alive()
1146 struct dirent *entry;
1147 struct stat filestat;
1153 dir = opendir("/proc");
1155 SLOG(LOG_ERROR, TAG_STTC, "process checking is FAILED");
1159 while ((entry = readdir(dir)) != NULL) {
1160 if (0 != lstat(entry->d_name, &filestat))
1163 if (!S_ISDIR(filestat.st_mode))
1166 pid = atoi(entry->d_name);
1167 if (pid <= 0) continue;
1169 sprintf(tempPath, "/proc/%d/cmdline", pid);
1170 if (0 != __get_cmd_line(tempPath, cmdLine)) {
1173 if ( 0 == strncmp(cmdLine, "[stt-daemon]", strlen("[stt-daemon]")) ||
1174 0 == strncmp(cmdLine, "stt-daemon", strlen("stt-daemon")) ||
1175 0 == strncmp(cmdLine, "/usr/bin/stt-daemon", strlen("/usr/bin/stt-daemon"))) {
1176 SLOG(LOG_DEBUG, TAG_STTC, "stt-daemon is ALIVE !! \n");
1181 SLOG(LOG_DEBUG, TAG_STTC, "THERE IS NO stt-daemon !! \n");
1189 static void __my_sig_child(int signo, siginfo_t *info, void *data)
1192 pid_t child_pid, child_pgid;
1194 child_pgid = getpgid(info->si_pid);
1195 SLOG(LOG_DEBUG, TAG_STTC, "Signal handler: dead pid = %d, pgid = %d\n", info->si_pid, child_pgid);
1197 while((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
1198 if(child_pid == child_pgid)
1199 killpg(child_pgid, SIGKILL);
1206 static int __check_stt_daemon()
1208 if( TRUE == __stt_is_alive() )
1211 /* fork-exec stt-daemon */
1213 struct sigaction act, dummy;
1215 act.sa_handler = NULL;
1216 act.sa_sigaction = __my_sig_child;
1217 sigemptyset(&act.sa_mask);
1218 act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
1220 if(sigaction(SIGCHLD, &act, &dummy) < 0) {
1221 SLOG(LOG_DEBUG, TAG_STTC, "%s\n", "Cannot make a signal handler\n");
1229 SLOG(LOG_DEBUG, TAG_STTC, "[STT ERROR] fail to create STT-DAEMON \n");
1234 for (i = 0;i < _NSIG;i++)
1237 execl("/usr/bin/stt-daemon", "/usr/bin/stt-daemon", NULL);