fix merge duplication
[platform/core/uifw/stt.git] / server / stte.c
1 /*
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.
12 */
13
14 #include <aul.h>
15 #include <Ecore.h>
16 #include <vconf.h>
17 #include <stdatomic.h>
18 #include <system_info.h>
19 #include <cynara-client.h>
20 #include <cynara-error.h>
21 #include <cynara-session.h>
22 #include <pthread.h>
23
24 #include "stt_engine.h"
25 #include "stt_defs.h"
26 #include "stt_network.h"
27 #include "sttd_dbus.h"
28 #include "sttd_server.h"
29 #include "sttd_engine_agent.h"
30 #include "stt_dlog.h"
31
32 #include "stte.h"
33
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;
37
38 static bool is_feature_enabled()
39 {
40         if (1 == g_feature_enabled) {
41                 return true;
42         }
43
44         if (0 == g_feature_enabled) {
45                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] TTS feature NOT supported");
46                 return false;
47         }
48
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");
52                 return false;
53         }
54
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");
58                 return false;
59         }
60
61         if (false == stt_supported || false == mic_supported) {
62                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] STT NOT supported");
63                 g_feature_enabled = 0;
64                 return false;
65         }
66
67         g_feature_enabled = 1;
68         return true;
69 }
70
71 static bool initialize_privilege_checker()
72 {
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
76
77         return ret == CYNARA_API_SUCCESS;
78 }
79
80 static bool is_privilege_allowed(const char* uid, const char * privilege)
81 {
82         FILE *fp = NULL;
83         char label_path[1024] = "/proc/self/attr/current";
84         char smack_label[1024] = {'\0',};
85
86         if (!p_cynara) {
87                 return false;
88         }
89
90         fp = fopen(label_path, "r");
91         if (fp != NULL) {
92                 if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
93                         SLOG(LOG_ERROR, TAG_STTD, "[ERROR] fail to fread"); //LCOV_EXCL_LINE
94
95                 fclose(fp);
96                 fp = NULL;
97         }
98
99         pid_t pid = getpid();
100         char *session = cynara_session_from_pid(pid);
101         int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
102         free(session);
103
104         if (ret != CYNARA_API_ACCESS_ALLOWED) {
105                 SLOG(LOG_ERROR, TAG_STTD, "[Client]cynara_check returned %d(Denied)", ret);
106                 return false;
107         }
108         return true;
109 }
110
111 static void deinitialize_privilege_checker()
112 {
113         if (p_cynara)
114                 cynara_finish(p_cynara);
115         p_cynara = NULL;
116 }
117
118 static bool is_stt_privilege_allowed()
119 {
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);
124                 return false;
125         }
126
127         char uid[16];
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);
133                 return false;
134         }
135
136         pthread_mutex_unlock(&g_cynara_mutex);
137         return true;
138 }
139
140 static inline int check_feature_and_privilege()
141 {
142         RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
143         RETV_IF(false == is_stt_privilege_allowed(), STTE_ERROR_PERMISSION_DENIED);
144
145         return STTE_ERROR_NONE;
146 }
147
148 static bool __is_default_engine()
149 {
150         char* engine = NULL;
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");
154                 return FALSE;
155         }
156
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");
160         }
161
162         SLOG(LOG_DEBUG, TAG_STTD, "[Server] STT Default Engine(%s), appId(%s)", engine, appid);
163         if (0 == strncmp(engine, appid, strlen(engine))) {
164                 free(engine);
165                 return TRUE;
166         }
167         free(engine);
168         return FALSE;
169 }
170
171 int stte_main(int argc, char**argv, stte_request_callback_s *callback)
172 {
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));
177                 return ret;
178         }
179
180         if (!ecore_init()) {
181                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize Ecore");
182                 return STTE_ERROR_OPERATION_FAILED;
183         }
184
185         if (TRUE == __is_default_engine()) {
186                 if (0 != sttd_dbus_open_connection()) {
187                         SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open connection");
188                         ecore_shutdown();
189                         return STTE_ERROR_OPERATION_FAILED;
190                 }
191         }
192
193         ret = sttd_initialize(callback);
194         if (0 != ret) {
195                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize stt-service");
196                 sttd_dbus_close_connection();
197                 ecore_shutdown();
198                 return ret;
199         }
200
201         stt_network_initialize();
202
203         SLOG(LOG_DEBUG, TAG_STTD, "[Main] stt-service start...");
204
205         SLOG(LOG_DEBUG, TAG_STTD, "=====");
206         SLOG(LOG_DEBUG, TAG_STTD, "  ");
207         SLOG(LOG_DEBUG, TAG_STTD, "  ");
208
209         return STTE_ERROR_NONE;
210 }
211
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)
214 {
215         RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
216
217         if (NULL == type || NULL == result) {
218                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Invalid parameter");
219         }
220
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);
225         } else {
226                 ret = sttd_engine_agent_send_result(event, type, result, result_count, msg, time_info, user_data);
227         }
228
229         if (STTE_ERROR_NONE != ret) {
230                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
231         }
232         return ret;
233 }
234
235 int stte_send_error(stte_error_e error, const char* msg)
236 {
237         RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
238
239         int ret = sttd_engine_agent_send_error(error, msg);
240         if (0 != ret) {
241                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info");
242         }
243         return ret;
244 }
245
246 int stte_send_speech_status(stte_speech_status_e status, void* user_data)
247 {
248         RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
249
250         int ret = sttd_engine_agent_send_speech_status(status, user_data);
251         if (0 != ret) {
252                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send speech status");
253         }
254         return ret;
255 }
256
257 int stte_set_private_data_set_cb(stte_private_data_set_cb callback)
258 {
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));
262                 return ret;
263         }
264
265         ret = stt_engine_set_private_data_set_cb(callback, NULL);
266         if (0 != ret) {
267                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data set callback");
268         }
269         return ret;
270 }
271
272 int stte_set_private_data_requested_cb(stte_private_data_requested_cb callback)
273 {
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));
277                 return ret;
278         }
279
280         ret = stt_engine_set_private_data_requested_cb(callback, NULL);
281         if (0 != ret) {
282                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data requested callback");
283         }
284         return ret;
285 }
286
287 int stte_set_audio_type_set_cb(stte_audio_type_cb callback, void* user_data)
288 {
289         SLOG(LOG_INFO, TAG_STTD, "[Server Info] Set audio type set callback");
290         RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
291
292         int ret = stt_engine_set_audio_type_set_cb(callback, user_data);
293         if (0 != ret) {
294                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio type set");
295         }
296         return ret;
297 }
298
299 int stte_unset_audio_type_set_cb(void)
300 {
301         SLOG(LOG_INFO, TAG_STTD, "[Server Info] Unset audio type set callback");
302         RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
303
304         int ret = stt_engine_unset_audio_type_set_cb();
305         if (0 != ret) {
306                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset audio type set");
307         }
308         return ret;
309 }