2 * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <cynara-client.h>
19 #include <cynara-error.h>
20 #include <cynara-session.h>
21 #include <system_info.h>
24 #include "vcd_server.h"
28 static int g_feature_enabled = -1;
29 static bool g_privilege_allowed = false;
31 static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
32 static cynara *p_cynara = NULL;
34 static int __vce_get_feature_enabled()
36 if (0 == g_feature_enabled) {
37 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Voice control feature NOT supported");
38 return VCE_ERROR_NOT_SUPPORTED;
39 } else if (-1 == g_feature_enabled) {
40 bool vc_supported = false;
41 bool mic_supported = false;
42 if (0 == system_info_get_platform_bool(VC_FEATURE_PATH, &vc_supported)) {
43 if (0 == system_info_get_platform_bool(VC_MIC_FEATURE_PATH, &mic_supported)) {
44 if (false == vc_supported || false == mic_supported) {
45 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Voice control feature NOT supported");
46 g_feature_enabled = 0;
47 return VCE_ERROR_NOT_SUPPORTED;
50 g_feature_enabled = 1;
52 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get feature value");
53 return VCE_ERROR_NOT_SUPPORTED;
56 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get feature value");
57 return VCE_ERROR_NOT_SUPPORTED;
61 return VCE_ERROR_NONE;
64 static int __check_privilege_initialize()
66 int ret = cynara_initialize(&p_cynara, NULL);
67 if (CYNARA_API_SUCCESS != ret)
68 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] fail to initialize");
70 return ret == CYNARA_API_SUCCESS;
73 static int __check_privilege(const char* uid, const char * privilege)
76 char label_path[1024] = "/proc/self/attr/current";
77 char smack_label[1024] = {'\0',};
83 fp = fopen(label_path, "r");
85 if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
86 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] fail to fread");
92 char *session = cynara_session_from_pid(pid);
93 int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
94 SLOG(LOG_INFO, TAG_VCD, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied");
98 if (ret != CYNARA_API_ACCESS_ALLOWED)
103 static void __check_privilege_deinitialize()
107 int ret = cynara_finish(p_cynara);
108 if (ret != CYNARA_API_SUCCESS)
109 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] cynara finish %d", ret);
114 static int __vce_check_privilege()
116 pthread_mutex_lock(&g_cynara_mutex);
118 if (true == g_privilege_allowed) {
119 pthread_mutex_unlock(&g_cynara_mutex);
120 return VC_ERROR_NONE;
124 ret = __check_privilege_initialize();
126 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] privilege initialize is failed");
127 pthread_mutex_unlock(&g_cynara_mutex);
128 return VCE_ERROR_PERMISSION_DENIED;
132 snprintf(uid, 32, "%d", getuid());
134 ret = __check_privilege(uid, VC_PRIVILEGE_RECORDER);
137 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_RECORDER, uid);
138 __check_privilege_deinitialize();
139 g_privilege_allowed = false;
140 pthread_mutex_unlock(&g_cynara_mutex);
141 return VCE_ERROR_PERMISSION_DENIED;
145 ret = __check_privilege(uid, VC_PRIVILEGE_APPMGR_LAUNCH);
148 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_APPMGR_LAUNCH, uid);
149 __check_privilege_deinitialize();
150 g_privilege_allowed = false;
151 pthread_mutex_unlock(&g_cynara_mutex);
152 return VCE_ERROR_PERMISSION_DENIED;
156 ret = __check_privilege(uid, VC_PRIVILEGE_DATASHARING);
159 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_DATASHARING, uid);
160 __check_privilege_deinitialize();
161 g_privilege_allowed = false;
162 pthread_mutex_unlock(&g_cynara_mutex);
163 return VCE_ERROR_PERMISSION_DENIED;
167 __check_privilege_deinitialize();
169 g_privilege_allowed = true;
170 pthread_mutex_unlock(&g_cynara_mutex);
171 return VCE_ERROR_NONE;
174 int __check_engine_feature_privilege()
176 if (0 != __vce_get_feature_enabled()) {
177 return VCE_ERROR_NOT_SUPPORTED;
179 if (0 != __vce_check_privilege()) {
180 return VCE_ERROR_PERMISSION_DENIED;
183 return VCE_ERROR_NONE;
186 int vce_main(int argc, char** argv, vce_request_callback_s *callback)
189 ret = __check_engine_feature_privilege();
190 if (VCE_ERROR_NONE != ret)
193 SLOG(LOG_DEBUG, TAG_VCD, " ");
194 SLOG(LOG_DEBUG, TAG_VCD, " ");
195 SLOG(LOG_INFO, TAG_VCD, "===== VC Engine Service Initialize");
197 ret = VCE_ERROR_NONE;
200 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail ecore_init()");
201 return VCE_ERROR_OPERATION_FAILED;
204 ret = vcd_initialize(callback);
206 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize");
211 SLOG(LOG_INFO, TAG_VCD, "[Main] VC Engine Service start...");
213 SLOG(LOG_DEBUG, TAG_VCD, "=====");
214 SLOG(LOG_DEBUG, TAG_VCD, " ");
215 SLOG(LOG_DEBUG, TAG_VCD, " ");
217 return VCE_ERROR_NONE;
220 int vce_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, int* user_info, void *user_data)
222 int ret = VCE_ERROR_NONE;
223 ret = __check_engine_feature_privilege();
224 if (VCE_ERROR_NONE != ret)
227 if (event < VCE_RESULT_EVENT_SUCCESS || event > VCE_RESULT_EVENT_ERROR) {
228 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
229 return VCE_ERROR_INVALID_PARAMETER;
232 if (NULL == all_result || NULL == non_fixed_result || NULL == nlu_result) {
233 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
236 ret = vcd_send_result(event, result_id, count, all_result, non_fixed_result, nlu_result, msg, user_info, user_data);
238 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send result");
240 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send result");
247 int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data)
249 int ret = VCE_ERROR_NONE;
250 ret = __check_engine_feature_privilege();
251 if (VCE_ERROR_NONE != ret)
254 if (event < VCE_ASR_RESULT_EVENT_FINAL_RESULT || event > VCE_ASR_RESULT_EVENT_ERROR) {
255 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
256 return VCE_ERROR_INVALID_PARAMETER;
259 if (NULL == asr_result) {
260 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
263 ret = vcd_send_asr_result(event, asr_result, user_data);
265 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send ASR result");
267 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send ASR result");
273 int vce_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info)
275 int ret = VCE_ERROR_NONE;
276 ret = __check_engine_feature_privilege();
277 if (VCE_ERROR_NONE != ret)
280 if (NULL == engine_app_id || NULL == event) {
281 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
282 return VCE_ERROR_INVALID_PARAMETER;
285 if (NULL == result) {
286 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
289 ret = vcd_send_specific_engine_result(engine_app_id, event, result, user_info);
291 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send specific engine result, ret(%d)", ret);
293 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send specific engine result, event(%s), result(%s)", event, result);
299 int vce_send_nlg_result(const char* nlg_result, void *user_data)
301 int ret = VCE_ERROR_NONE;
302 ret = __check_engine_feature_privilege();
303 if (VCE_ERROR_NONE != ret)
306 if (NULL == nlg_result) {
307 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
310 ret = vcd_send_nlg_result(nlg_result, user_data);
312 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send NLG result");
314 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send NLG result");
320 int vce_send_error(vce_error_e error, const char* msg, void *user_data)
322 int ret = VCE_ERROR_NONE;
323 ret = __check_engine_feature_privilege();
324 if (VCE_ERROR_NONE != ret)
328 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Input parameter is NULL. (no error message)");
331 ret = vcd_send_error(error, msg, user_data);
334 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send error");
342 int vce_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
344 if (0 != __vce_get_feature_enabled()) {
345 return VCE_ERROR_NOT_SUPPORTED;
348 int ret = VCE_ERROR_NONE;
350 ret = vcd_get_foreach_command(vce_command, callback, user_data);
352 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get foreach command");
358 int vce_get_command_count(vce_cmd_h vce_command, int* count)
360 if (0 != __vce_get_feature_enabled()) {
361 return VCE_ERROR_NOT_SUPPORTED;
364 int ret = VCE_ERROR_NONE;
367 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
368 return VCE_ERROR_INVALID_PARAMETER;
370 ret = vcd_get_command_count(vce_command, count);
372 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get command count");
378 int vce_get_audio_type(char** audio_type)
381 ret = __check_engine_feature_privilege();
382 if (VCE_ERROR_NONE != ret)
385 ret = vcd_get_audio_type(audio_type);
387 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get audio type");
393 int vce_set_private_data(const char* key, const char* data)
396 ret = __check_engine_feature_privilege();
397 if (VCE_ERROR_NONE != ret)
400 if (NULL == key || NULL == data) {
401 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
402 return VCE_ERROR_INVALID_PARAMETER;
405 // TODO: Shoud be added updateEvent to client, need to ACR for update state.
406 // if (!strncmp(key, "UpdateEventStart", strlen(key)))
407 // ret = vce_send_update_status(VCE_UPDATE_EVENT_START, NULL);
408 // else if (!strncmp(key, "UpdateEventComplete", strlen(key)))
409 // ret = vce_send_update_status(VCE_UPDATE_EVENT_FINISH, NULL);
410 // else if (!strncmp(key, "UpdateEventFail", strlen(key)))
411 // ret = vce_send_update_status(VCE_UPDATE_EVENT_FAIL, data);
413 // SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send update status, event(%s), msg(%s): ret(%d)", key, data, ret);
417 ret = vcd_set_private_data(key, data);
419 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data to vc manager");
425 int vce_get_private_data(const char* key, char** data)
428 ret = __check_engine_feature_privilege();
429 if (VCE_ERROR_NONE != ret)
432 if (NULL == key || NULL == data) {
433 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
434 return VCE_ERROR_INVALID_PARAMETER;
437 ret = vcd_get_private_data(key, data);
439 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get private data from vc manager");
445 int vce_start_recording()
448 ret = __check_engine_feature_privilege();
449 if (VCE_ERROR_NONE != ret)
452 ret = vcd_start_recording();
454 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start recording");
460 int vce_stop_recording()
463 ret = __check_engine_feature_privilege();
464 if (VCE_ERROR_NONE != ret)
467 ret = vcd_stop_recording();
469 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to stop recording");
475 int vce_send_update_status(vce_update_event_e update_event, const char* msg)
478 ret = __check_engine_feature_privilege();
479 if (VCE_ERROR_NONE != ret)
482 ret = vcd_send_update_status(update_event, msg);
484 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send update status");
490 int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func)
493 ret = __check_engine_feature_privilege();
494 if (VCE_ERROR_NONE != ret)
497 if (NULL == callback_func) {
498 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
499 return VCE_ERROR_INVALID_PARAMETER;
502 ret = vcd_set_private_data_set_cb(callback_func);
504 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data set cb");
510 int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
513 ret = __check_engine_feature_privilege();
514 if (VCE_ERROR_NONE != ret)
517 if (NULL == callback_func) {
518 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
519 return VCE_ERROR_INVALID_PARAMETER;
522 ret = vcd_set_private_data_requested_cb(callback_func);
524 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data requested cb");
530 int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
532 if (0 != __vce_get_feature_enabled()) {
533 return VCE_ERROR_NOT_SUPPORTED;
536 if (NULL == callback_func) {
537 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
538 return VCE_ERROR_INVALID_PARAMETER;
541 int ret = vcd_set_nlu_base_info_requested_cb(callback_func);
543 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set nlu-base info requested cb");
549 int vce_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func)
551 if (0 != __vce_get_feature_enabled()) {
552 return VCE_ERROR_NOT_SUPPORTED;
555 if (NULL == callback_func) {
556 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
557 return VCE_ERROR_INVALID_PARAMETER;
560 int ret = vcd_set_specific_engine_request_cb(callback_func);
562 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set specific engine request cb");
568 int vce_unset_specific_engine_request_cb(void)
570 if (0 != __vce_get_feature_enabled()) {
571 return VCE_ERROR_NOT_SUPPORTED;
574 int ret = vcd_set_specific_engine_request_cb(NULL);
576 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset specific engine request cb");
582 /* for TTS feedback */
583 int vce_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type)
585 int ret = VCE_ERROR_NONE;
586 ret = __check_engine_feature_privilege();
587 if (VCE_ERROR_NONE != ret)
590 if (channel < VCE_AUDIO_CHANNEL_MONO || channel > VCE_AUDIO_CHANNEL_STEREO) {
591 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
592 return VCE_ERROR_INVALID_PARAMETER;
595 if (audio_type < VCE_AUDIO_TYPE_PCM_S16_LE || audio_type > VCE_AUDIO_TYPE_PCM_U8) {
596 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
597 return VCE_ERROR_INVALID_PARAMETER;
600 ret = vcd_send_feedback_audio_format(rate, channel, audio_type);
602 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send feedback audio format");
608 int vce_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len)
610 int ret = VCE_ERROR_NONE;
611 ret = __check_engine_feature_privilege();
612 if (VCE_ERROR_NONE != ret)
615 if (NULL == buffer) {
616 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Input parameter is NULL");
617 return VCE_ERROR_INVALID_PARAMETER;
620 ret = vcd_send_feedback_streaming(event, buffer, len);
622 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send feedback streaming");
628 int vce_set_request_tts_cb(vce_request_tts_cb callback_func, void* user_data)
630 if (NULL == callback_func) {
631 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
632 return VCE_ERROR_INVALID_PARAMETER;
635 int ret = vcd_set_request_tts_cb(callback_func, user_data);
637 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set request tts cb");
643 int vce_unset_request_tts_cb(void)
645 int ret = vcd_set_request_tts_cb(NULL, NULL);
647 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset request tts cb");
653 int vce_set_cancel_tts_cb(vce_cancel_tts_cb callback_func, void* user_data)
655 if (NULL == callback_func) {
656 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
657 return VCE_ERROR_INVALID_PARAMETER;
660 int ret = vcd_set_cancel_tts_cb(callback_func, user_data);
662 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set cancel tts cb");
668 int vce_unset_cancel_tts_cb(void)
670 int ret = vcd_set_cancel_tts_cb(NULL, NULL);
672 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset cancel tts cb");
678 int vce_set_tts_audio_format_request_cb(vce_tts_audio_format_request_cb callback_func, void* user_data)
680 if (NULL == callback_func) {
681 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
682 return VCE_ERROR_INVALID_PARAMETER;
685 int ret = vcd_set_tts_audio_format_request_cb(callback_func, user_data);
687 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set get tts audio format cb");
693 int vce_unset_get_tts_audio_format_cb(void)
695 int ret = vcd_set_tts_audio_format_request_cb(NULL, NULL);
697 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset request tts cb");