2 * Copyright (c) 2011-2016 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.
17 #include <stdatomic.h>
18 #include <system_info.h>
19 #include <cynara-client.h>
20 #include <cynara-error.h>
21 #include <cynara-session.h>
24 #include "stt_engine.h"
26 #include "stt_network.h"
27 #include "sttd_dbus.h"
28 #include "sttd_server.h"
29 #include "sttd_engine_agent.h"
34 static atomic_int g_feature_enabled = -1;
35 static cynara *p_cynara = NULL;
36 static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
38 static bool is_feature_enabled()
40 if (1 == g_feature_enabled) {
44 if (0 == g_feature_enabled) {
45 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] TTS feature NOT supported");
49 bool stt_supported = false;
50 if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool(STT_FEATURE_PATH, &stt_supported)) {
51 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to get feature value");
55 bool mic_supported = false;
56 if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool(STT_MIC_FEATURE_PATH, &mic_supported)) {
57 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to get feature value");
61 if (false == stt_supported || false == mic_supported) {
62 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] STT NOT supported");
63 g_feature_enabled = 0;
67 g_feature_enabled = 1;
71 static bool initialize_privilege_checker()
73 int ret = cynara_initialize(&p_cynara, NULL);
74 if (CYNARA_API_SUCCESS != ret)
75 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] fail to initialize"); //LCOV_EXCL_LINE
77 return ret == CYNARA_API_SUCCESS;
80 static bool is_privilege_allowed(const char* uid, const char * privilege)
83 char label_path[1024] = "/proc/self/attr/current";
84 char smack_label[1024] = {'\0',};
90 fp = fopen(label_path, "r");
92 if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
93 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] fail to fread"); //LCOV_EXCL_LINE
100 char *session = cynara_session_from_pid(pid);
101 int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
104 if (ret != CYNARA_API_ACCESS_ALLOWED) {
105 SLOG(LOG_ERROR, TAG_STTD, "[Client]cynara_check returned %d(Denied)", ret);
111 static void deinitialize_privilege_checker()
114 cynara_finish(p_cynara);
118 static bool is_stt_privilege_allowed()
120 pthread_mutex_lock(&g_cynara_mutex);
121 bool is_initialized = initialize_privilege_checker();
122 if (false == is_initialized) {
123 pthread_mutex_unlock(&g_cynara_mutex);
128 snprintf(uid, 16, "%d", getuid());
129 bool is_allowed = is_privilege_allowed(uid, STT_PRIVILEGE_RECORDER);
130 deinitialize_privilege_checker();
131 if (false == is_allowed) {
132 pthread_mutex_unlock(&g_cynara_mutex);
136 pthread_mutex_unlock(&g_cynara_mutex);
140 static inline int check_feature_and_privilege()
142 RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
143 RETV_IF(false == is_stt_privilege_allowed(), STTE_ERROR_PERMISSION_DENIED);
145 return STTE_ERROR_NONE;
148 static bool __is_default_engine()
151 engine = vconf_get_str(VCONFKEY_STT_ENGINE_DEFAULT);
152 if (NULL == engine) {
153 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get sting for stt engine");
157 char appid[1024] = {'\0', };
158 if (0 != aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1)) {
159 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get callee appid by pid");
162 SLOG(LOG_DEBUG, TAG_STTD, "[Server] STT Default Engine(%s), appId(%s)", engine, appid);
163 if (0 == strncmp(engine, appid, strlen(engine))) {
171 int stte_main(int argc, char**argv, stte_request_callback_s *callback)
173 SLOG(LOG_DEBUG, TAG_STTD, "===== Start engine");
174 int ret = check_feature_and_privilege();
175 if (STTE_ERROR_NONE != ret) {
176 SLOG(LOG_ERROR, TAG_STTD, "Precondition is not met (%s)", get_error_message(ret));
181 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize Ecore");
182 return STTE_ERROR_OPERATION_FAILED;
185 if (TRUE == __is_default_engine()) {
186 if (0 != sttd_dbus_open_connection()) {
187 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open connection");
189 return STTE_ERROR_OPERATION_FAILED;
193 ret = sttd_initialize(callback);
195 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize stt-service");
196 sttd_dbus_close_connection();
201 stt_network_initialize();
203 SLOG(LOG_DEBUG, TAG_STTD, "[Main] stt-service start...");
205 SLOG(LOG_DEBUG, TAG_STTD, "=====");
206 SLOG(LOG_DEBUG, TAG_STTD, " ");
207 SLOG(LOG_DEBUG, TAG_STTD, " ");
209 return STTE_ERROR_NONE;
212 int stte_send_result(stte_result_event_e event, const char* type, const char** result, int result_count,
213 const char* msg, void* time_info, void* user_data)
215 RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
217 if (NULL == type || NULL == result) {
218 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Invalid parameter");
221 stt_engine_result_cb result_cb = NULL;
222 int ret = stt_engine_get_recognition_result_cb(&result_cb);
223 if (STTE_ERROR_NONE == ret && NULL != result_cb) {
224 ret = result_cb(event, type, result, result_count, msg, time_info, user_data);
226 ret = sttd_engine_agent_send_result(event, type, result, result_count, msg, time_info, user_data);
229 if (STTE_ERROR_NONE != ret) {
230 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
235 int stte_send_error(stte_error_e error, const char* msg)
237 RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
239 int ret = sttd_engine_agent_send_error(error, msg);
241 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info");
246 int stte_send_speech_status(stte_speech_status_e status, void* user_data)
248 RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
250 int ret = sttd_engine_agent_send_speech_status(status, user_data);
252 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send speech status");
257 int stte_set_private_data_set_cb(stte_private_data_set_cb callback)
259 int ret = check_feature_and_privilege();
260 if (STTE_ERROR_NONE != ret) {
261 SLOG(LOG_ERROR, TAG_STTD, "Precondition is not met (%s)", get_error_message(ret));
265 ret = stt_engine_set_private_data_set_cb(callback, NULL);
267 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data set callback");
272 int stte_set_private_data_requested_cb(stte_private_data_requested_cb callback)
274 int ret = check_feature_and_privilege();
275 if (STTE_ERROR_NONE != ret) {
276 SLOG(LOG_ERROR, TAG_STTD, "Precondition is not met (%s)", get_error_message(ret));
280 ret = stt_engine_set_private_data_requested_cb(callback, NULL);
282 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data requested callback");
287 int stte_set_audio_type_set_cb(stte_audio_type_cb callback, void* user_data)
289 SLOG(LOG_INFO, TAG_STTD, "[Server Info] Set audio type set callback");
290 RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
292 int ret = stt_engine_set_audio_type_set_cb(callback, user_data);
294 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio type set");
299 int stte_unset_audio_type_set_cb(void)
301 SLOG(LOG_INFO, TAG_STTD, "[Server Info] Unset audio type set callback");
302 RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
304 int ret = stt_engine_unset_audio_type_set_cb();
306 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset audio type set");