1/*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
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 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16//! fusion IPC client.
17
18#![allow(dead_code)]
19#![allow(unused_variables)]
20
21mod frameworks;
22
23use std::ffi::{ c_char, CStr, CString };
24use std::os::fd::AsRawFd;
25use hilog_rust::{ error, hilog, HiLogLabel, LogType };
26use fusion_utils_rust::call_debug_enter;
27use fusion_data_rust::{ AllocSocketPairParam, CDragData, DragData };
28use frameworks::FusionFrameworks;
29
30const LOG_LABEL: HiLogLabel = HiLogLabel {
31    log_type: LogType::LogCore,
32    domain: 0xD002220,
33    tag: "fusion_client"
34};
35
36/// # Safety
37#[no_mangle]
38unsafe extern "C" fn fusion_alloc_socket_fd(program_name: *const c_char, module_type: i32,
39    client_fd: *mut i32, token_type: *mut i32) -> i32
40{
41    call_debug_enter!("fusion_alloc_socket_fd");
42    if program_name.is_null() {
43        error!(LOG_LABEL, "program_name is null");
44        return -1;
45    };
46    let param = match AllocSocketPairParam::from_c(program_name, module_type) {
47        Ok(param) => { param }
48        Err(err) => {
49            error!(LOG_LABEL, "Failed parsing AllocSocketPairParam");
50            return i32::from(err);
51        }
52    };
53    let fw = FusionFrameworks::get_instance().unwrap();
54    fw.alloc_socket_pair(&param).map_or_else(
55        |err| { i32::from(err) },
56        |(fdesc, t)| {
57            *client_fd = fdesc.as_raw_fd();
58            *token_type = t;
59            0
60        }
61    )
62}
63
64/// # Safety
65#[no_mangle]
66unsafe extern "C" fn fusion_start_drag(c_drag_data: *mut CDragData) -> i32
67{
68    c_drag_data.as_mut().map_or(-1, |c_drag_data_ref| {
69        let drag_data = DragData::from_c(c_drag_data_ref);
70        let fw = FusionFrameworks::get_instance().unwrap();
71        fw.start_drag(&drag_data).map_or_else(|err| { i32::from(err) }, |_| { 0 })
72    })
73}
74
75/// # Safety
76#[no_mangle]
77unsafe extern "C" fn fusion_register_coordination_listener() -> i32
78{
79    let fw = FusionFrameworks::get_instance().unwrap();
80    fw.register_coordination_listener().map_or_else(|err| { i32::from(err) }, |_| { 0 })
81}
82
83/// # Safety
84#[no_mangle]
85unsafe extern "C" fn fusion_unregister_coordination_listener() -> i32
86{
87    let fw = FusionFrameworks::get_instance().unwrap();
88    fw.unregister_coordination_listener().map_or_else(|err| { i32::from(err) }, |_| { 0 })
89}
90
91/// # Safety
92#[no_mangle]
93unsafe extern "C" fn fusion_enable_coordination(user_data: i32) -> i32
94{
95    let fw = FusionFrameworks::get_instance().unwrap();
96    fw.enable_coordination(user_data).map_or_else(|err| { i32::from(err) }, |_| { 0 })
97}
98
99/// # Safety
100#[no_mangle]
101unsafe extern "C" fn fusion_disable_coordination(user_data: i32) -> i32
102{
103    let fw = FusionFrameworks::get_instance().unwrap();
104    fw.disable_coordination(user_data).map_or_else(|err| { i32::from(err) }, |_| { 0 })
105}
106
107/// # Safety
108#[no_mangle]
109unsafe extern "C" fn fusion_start_coordination(user_data: i32,
110    remote_network_id: *const c_char, start_device_id: i32) -> i32
111{
112    if remote_network_id.is_null() {
113        error!(LOG_LABEL, "remote_network_id is null");
114        return -1;
115    }
116    let remote_network_id: String = match CStr::from_ptr(remote_network_id).to_str() {
117        Ok(id) => { id.to_string() }
118        Err(_) => {
119            error!(LOG_LABEL, "Invalid network id");
120            return -1;
121        }
122    };
123    let fw = FusionFrameworks::get_instance().unwrap();
124    fw.start_coordination(user_data, &remote_network_id,
125        start_device_id).map_or_else(|err| { i32::from(err) }, |_| { 0 })
126}
127
128/// # Safety
129#[no_mangle]
130unsafe extern "C" fn fusion_stop_coordination(user_data: i32, is_unchained: i32) -> i32
131{
132    let fw = FusionFrameworks::get_instance().unwrap();
133    fw.stop_coordination(user_data, is_unchained).map_or_else(|err| { i32::from(err) }, |_| { 0 })
134}
135
136/// # Safety
137#[no_mangle]
138unsafe extern "C" fn fusion_get_coordination_state(user_data: i32, device_id: *const c_char) -> i32
139{
140    if device_id.is_null() {
141        error!(LOG_LABEL, "device_id is null");
142        return -1;
143    }
144    let device_id: String = match CStr::from_ptr(device_id).to_str() {
145        Ok(id) => { id.to_string() }
146        Err(_) => {
147            error!(LOG_LABEL, "Invalid device id");
148            return -1;
149        }
150    };
151    let fw = FusionFrameworks::get_instance().unwrap();
152    fw.get_coordination_state(user_data, &device_id).map_or_else(|err| { i32::from(err) }, |_| { 0 })
153}
154