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 if (true == g_privilege_allowed)
117 return VC_ERROR_NONE;
119 pthread_mutex_lock(&g_cynara_mutex);
121 if (false == g_privilege_allowed) {
123 ret = __check_privilege_initialize();
125 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] privilege initialize is failed");
126 pthread_mutex_unlock(&g_cynara_mutex);
127 return VCE_ERROR_PERMISSION_DENIED;
131 snprintf(uid, 32, "%d", getuid());
133 ret = __check_privilege(uid, VC_PRIVILEGE_RECORDER);
136 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_RECORDER, uid);
137 __check_privilege_deinitialize();
138 g_privilege_allowed = false;
139 pthread_mutex_unlock(&g_cynara_mutex);
140 return VCE_ERROR_PERMISSION_DENIED;
144 ret = __check_privilege(uid, VC_PRIVILEGE_APPMGR_LAUNCH);
147 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_APPMGR_LAUNCH, uid);
148 __check_privilege_deinitialize();
149 g_privilege_allowed = false;
150 pthread_mutex_unlock(&g_cynara_mutex);
151 return VCE_ERROR_PERMISSION_DENIED;
155 ret = __check_privilege(uid, VC_PRIVILEGE_DATASHARING);
158 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_DATASHARING, uid);
159 __check_privilege_deinitialize();
160 g_privilege_allowed = false;
161 pthread_mutex_unlock(&g_cynara_mutex);
162 return VCE_ERROR_PERMISSION_DENIED;
166 __check_privilege_deinitialize();
170 g_privilege_allowed = true;
171 pthread_mutex_unlock(&g_cynara_mutex);
172 return VCE_ERROR_NONE;
175 int __check_engine_feature_privilege()
177 if (0 != __vce_get_feature_enabled()) {
178 return VCE_ERROR_NOT_SUPPORTED;
180 if (0 != __vce_check_privilege()) {
181 return VCE_ERROR_PERMISSION_DENIED;
184 return VCE_ERROR_NONE;
187 int vce_main(int argc, char** argv, vce_request_callback_s *callback)
190 ret = __check_engine_feature_privilege();
191 if (VCE_ERROR_NONE != ret)
194 SLOG(LOG_DEBUG, TAG_VCD, " ");
195 SLOG(LOG_DEBUG, TAG_VCD, " ");
196 SLOG(LOG_INFO, TAG_VCD, "===== VC Engine Service Initialize");
198 ret = VCE_ERROR_NONE;
201 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail ecore_init()");
202 return VCE_ERROR_OPERATION_FAILED;
205 ret = vcd_initialize(callback);
207 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize");
212 SLOG(LOG_INFO, TAG_VCD, "[Main] VC Engine Service start...");
214 SLOG(LOG_DEBUG, TAG_VCD, "=====");
215 SLOG(LOG_DEBUG, TAG_VCD, " ");
216 SLOG(LOG_DEBUG, TAG_VCD, " ");
218 return VCE_ERROR_NONE;
221 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)
223 int ret = VCE_ERROR_NONE;
224 ret = __check_engine_feature_privilege();
225 if (VCE_ERROR_NONE != ret)
228 if (event < VCE_RESULT_EVENT_SUCCESS || event > VCE_RESULT_EVENT_ERROR) {
229 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
230 return VCE_ERROR_INVALID_PARAMETER;
233 if (NULL == all_result || NULL == non_fixed_result || NULL == nlu_result) {
234 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
237 ret = vcd_send_result(event, result_id, count, all_result, non_fixed_result, nlu_result, msg, user_info, user_data);
239 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send result");
241 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send result");
248 int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data)
250 int ret = VCE_ERROR_NONE;
251 ret = __check_engine_feature_privilege();
252 if (VCE_ERROR_NONE != ret)
255 if (event < VCE_ASR_RESULT_EVENT_FINAL_RESULT || event > VCE_ASR_RESULT_EVENT_ERROR) {
256 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
257 return VCE_ERROR_INVALID_PARAMETER;
260 if (NULL == asr_result) {
261 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
264 ret = vcd_send_asr_result(event, asr_result, user_data);
266 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send ASR result");
268 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send ASR result");
274 int vce_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info)
276 int ret = VCE_ERROR_NONE;
277 ret = __check_engine_feature_privilege();
278 if (VCE_ERROR_NONE != ret)
281 if (NULL == engine_app_id || NULL == event) {
282 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
283 return VCE_ERROR_INVALID_PARAMETER;
286 if (NULL == result) {
287 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
290 ret = vcd_send_specific_engine_result(engine_app_id, event, result, user_info);
292 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send specific engine result, ret(%d)", ret);
294 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send specific engine result, event(%s), result(%s)", event, result);
300 int vce_send_nlg_result(const char* nlg_result, void *user_data)
302 int ret = VCE_ERROR_NONE;
303 ret = __check_engine_feature_privilege();
304 if (VCE_ERROR_NONE != ret)
307 if (NULL == nlg_result) {
308 SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)");
311 ret = vcd_send_nlg_result(nlg_result, user_data);
313 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send NLG result");
315 SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send NLG result");
321 int vce_send_error(vce_error_e error, const char* msg, void *user_data)
323 int ret = VCE_ERROR_NONE;
324 ret = __check_engine_feature_privilege();
325 if (VCE_ERROR_NONE != ret)
329 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Input parameter is NULL. (no error message)");
332 ret = vcd_send_error(error, msg, user_data);
335 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send error");
343 int vce_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
345 if (0 != __vce_get_feature_enabled()) {
346 return VCE_ERROR_NOT_SUPPORTED;
349 int ret = VCE_ERROR_NONE;
351 ret = vcd_get_foreach_command(vce_command, callback, user_data);
353 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get foreach command");
359 int vce_get_command_count(vce_cmd_h vce_command, int* count)
361 if (0 != __vce_get_feature_enabled()) {
362 return VCE_ERROR_NOT_SUPPORTED;
365 int ret = VCE_ERROR_NONE;
368 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
369 return VCE_ERROR_INVALID_PARAMETER;
371 ret = vcd_get_command_count(vce_command, count);
373 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get command count");
379 int vce_get_audio_type(char** audio_type)
382 ret = __check_engine_feature_privilege();
383 if (VCE_ERROR_NONE != ret)
386 ret = vcd_get_audio_type(audio_type);
388 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get audio type");
394 int vce_set_private_data(const char* key, const char* data)
397 ret = __check_engine_feature_privilege();
398 if (VCE_ERROR_NONE != ret)
401 if (NULL == key || NULL == data) {
402 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
403 return VCE_ERROR_INVALID_PARAMETER;
406 // TODO: Shoud be added updateEvent to client, need to ACR for update state.
407 // if (!strncmp(key, "UpdateEventStart", strlen(key)))
408 // ret = vce_send_update_status(VCE_UPDATE_EVENT_START, NULL);
409 // else if (!strncmp(key, "UpdateEventComplete", strlen(key)))
410 // ret = vce_send_update_status(VCE_UPDATE_EVENT_FINISH, NULL);
411 // else if (!strncmp(key, "UpdateEventFail", strlen(key)))
412 // ret = vce_send_update_status(VCE_UPDATE_EVENT_FAIL, data);
414 // SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send update status, event(%s), msg(%s): ret(%d)", key, data, ret);
418 ret = vcd_set_private_data(key, data);
420 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data to vc manager");
426 int vce_get_private_data(const char* key, char** data)
429 ret = __check_engine_feature_privilege();
430 if (VCE_ERROR_NONE != ret)
433 if (NULL == key || NULL == data) {
434 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
435 return VCE_ERROR_INVALID_PARAMETER;
438 ret = vcd_get_private_data(key, data);
440 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get private data from vc manager");
446 int vce_start_recording()
449 ret = __check_engine_feature_privilege();
450 if (VCE_ERROR_NONE != ret)
453 ret = vcd_start_recording();
455 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start recording");
461 int vce_stop_recording()
464 ret = __check_engine_feature_privilege();
465 if (VCE_ERROR_NONE != ret)
468 ret = vcd_stop_recording();
470 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to stop recording");
476 int vce_send_update_status(vce_update_event_e update_event, const char* msg)
479 ret = __check_engine_feature_privilege();
480 if (VCE_ERROR_NONE != ret)
483 ret = vcd_send_update_status(update_event, msg);
485 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send update status");
491 int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func)
494 ret = __check_engine_feature_privilege();
495 if (VCE_ERROR_NONE != ret)
498 if (NULL == callback_func) {
499 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
500 return VCE_ERROR_INVALID_PARAMETER;
503 ret = vcd_set_private_data_set_cb(callback_func);
505 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data set cb");
511 int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
514 ret = __check_engine_feature_privilege();
515 if (VCE_ERROR_NONE != ret)
518 if (NULL == callback_func) {
519 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
520 return VCE_ERROR_INVALID_PARAMETER;
523 ret = vcd_set_private_data_requested_cb(callback_func);
525 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data requested cb");
531 int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
533 if (0 != __vce_get_feature_enabled()) {
534 return VCE_ERROR_NOT_SUPPORTED;
537 if (NULL == callback_func) {
538 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
539 return VCE_ERROR_INVALID_PARAMETER;
542 int ret = vcd_set_nlu_base_info_requested_cb(callback_func);
544 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set nlu-base info requested cb");
550 int vce_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func)
552 if (0 != __vce_get_feature_enabled()) {
553 return VCE_ERROR_NOT_SUPPORTED;
556 if (NULL == callback_func) {
557 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
558 return VCE_ERROR_INVALID_PARAMETER;
561 int ret = vcd_set_specific_engine_request_cb(callback_func);
563 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set specific engine request cb");
569 int vce_unset_specific_engine_request_cb(void)
571 if (0 != __vce_get_feature_enabled()) {
572 return VCE_ERROR_NOT_SUPPORTED;
575 int ret = vcd_set_specific_engine_request_cb(NULL);
577 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset specific engine request cb");
583 /* for TTS feedback */
584 int vce_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type)
586 int ret = VCE_ERROR_NONE;
587 ret = __check_engine_feature_privilege();
588 if (VCE_ERROR_NONE != ret)
591 if (channel < VCE_AUDIO_CHANNEL_MONO || channel > VCE_AUDIO_CHANNEL_STEREO) {
592 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
593 return VCE_ERROR_INVALID_PARAMETER;
596 if (audio_type < VCE_AUDIO_TYPE_PCM_S16_LE || audio_type > VCE_AUDIO_TYPE_PCM_U8) {
597 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
598 return VCE_ERROR_INVALID_PARAMETER;
601 ret = vcd_send_feedback_audio_format(rate, channel, audio_type);
603 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send feedback audio format");
609 int vce_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len)
611 int ret = VCE_ERROR_NONE;
612 ret = __check_engine_feature_privilege();
613 if (VCE_ERROR_NONE != ret)
616 if (NULL == buffer) {
617 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Input parameter is NULL");
618 return VCE_ERROR_INVALID_PARAMETER;
621 ret = vcd_send_feedback_streaming(event, buffer, len);
623 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send feedback streaming");
629 int vce_set_request_tts_cb(vce_request_tts_cb callback_func, void* user_data)
631 if (NULL == callback_func) {
632 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
633 return VCE_ERROR_INVALID_PARAMETER;
636 int ret = vcd_set_request_tts_cb(callback_func, user_data);
638 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set request tts cb");
644 int vce_unset_request_tts_cb(void)
646 int ret = vcd_set_request_tts_cb(NULL, NULL);
648 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset request tts cb");
654 int vce_set_cancel_tts_cb(vce_cancel_tts_cb callback_func, void* user_data)
656 if (NULL == callback_func) {
657 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
658 return VCE_ERROR_INVALID_PARAMETER;
661 int ret = vcd_set_cancel_tts_cb(callback_func, user_data);
663 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set cancel tts cb");
669 int vce_unset_cancel_tts_cb(void)
671 int ret = vcd_set_cancel_tts_cb(NULL, NULL);
673 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset cancel tts cb");
679 int vce_set_tts_audio_format_request_cb(vce_tts_audio_format_request_cb callback_func, void* user_data)
681 if (NULL == callback_func) {
682 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
683 return VCE_ERROR_INVALID_PARAMETER;
686 int ret = vcd_set_tts_audio_format_request_cb(callback_func, user_data);
688 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set get tts audio format cb");
694 int vce_unset_get_tts_audio_format_cb(void)
696 int ret = vcd_set_tts_audio_format_request_cb(NULL, NULL);
698 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to unset request tts cb");