* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#[allow(unused)]
use crate::config::*;
#[allow(unused)]
use crate::serializer;
#[allow(unused)]
use crate::serializer::serialize::Serialization;
use crate::serializer::serialize::SerializedBuffer;
use crate::transfer::base;
use crate::transfer::base::Writer;
use crate::transfer::buffer::ConnectTypeMap;
use crate::utils;
#[allow(unused)]
use crate::utils::hdc_log::*;
use std::collections::HashMap;
#[allow(unused)]
use std::io::{self, Error, ErrorKind};
use std::sync::Arc;
use ylong_runtime::sync::{Mutex, RwLock};
#[repr(C)]
pub struct PersistBuffer {
pub ptr: *const libc::c_char,
pub size: libc::c_ulonglong,
}
#[allow(unused)]
pub fn buf_to_vec(buf: PersistBuffer) -> Vec<u8> {
let slice =
unsafe { std::slice::from_raw_parts(buf.ptr as *const libc::c_uchar, buf.size as usize) };
slice.to_vec()
}
#[allow(unused)]
extern "C" {
fn InitBridge() -> *mut libc::c_void;
fn StartListen(ptr: *mut libc::c_void) -> libc::c_int;
fn AcceptServerSocketFd(ptr: *mut libc::c_void, pipeFd: i32) -> libc::c_int;
fn InitClientFd(ptr: *mut libc::c_void, socketFd: i32) -> libc::c_int;
fn ReadClient(ptr: *mut libc::c_void, fd: i32, excepted_size: i32) -> PersistBuffer;
fn WriteClient(ptr: *mut libc::c_void, fd: i32, buf: SerializedBuffer) -> libc::c_int;
fn Stop(ptr: *mut libc::c_void) -> libc::c_int;
}
#[allow(unused)]
pub fn init_bridge() -> *mut libc::c_void {
unsafe { InitBridge() }
}
#[allow(unused)]
pub fn start_listen(ptr: u64) -> i32 {
unsafe { StartListen(ptr as *mut libc::c_void) }
}
#[allow(unused)]
pub fn accept_server_socket_fd(ptr: u64, pipe_fd: i32) -> i32 {
unsafe { AcceptServerSocketFd(ptr as *mut libc::c_void, pipe_fd) }
}
#[allow(unused)]
pub fn init_client_fd(ptr: u64, socket_fd: i32) -> i32 {
unsafe { InitClientFd(ptr as *mut libc::c_void, socket_fd) }
}
#[allow(unused)]
pub fn write_client(ptr: u64, fd: i32, buf: SerializedBuffer) -> i32 {
unsafe { WriteClient(ptr as *mut libc::c_void, fd, buf) }
}
#[allow(unused)]
pub fn read_client(ptr: u64, fd: i32, excepted_size: i32) -> PersistBuffer {
unsafe { ReadClient(ptr as *mut libc::c_void, fd, excepted_size) }
}
#[allow(unused)]
pub fn stop(ptr: u64) -> i32 {
unsafe { Stop(ptr as *mut libc::c_void) }
}
pub struct BridgeReader {
pub ptr: u64,
pub fd: i32,
}
pub struct BridgeWriter {
pub ptr: u64,
pub fd: i32,
}
impl base::Reader for BridgeReader {
fn read_frame(&self, _expected_size: usize) -> io::Result<Vec<u8>> {
let buf = read_client(self.ptr, self.fd, _expected_size as i32);
if buf.size == 0 {
crate::warn!("bridge read result <= 0");
return Err(utils::error_other("bridge read error".to_string()));
}
Ok(buf_to_vec(buf))
}
fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> {
Ok((0, 0, 0))
}
}
impl base::Writer for BridgeWriter {
fn write_all(&self, data: Vec<u8>) -> io::Result<i32> {
let buf = SerializedBuffer {
ptr: data.as_ptr() as *const libc::c_char,
size: data.len() as u64,
};
let ret = write_client(self.ptr, self.fd, buf);
if ret <= 0 {
Err(utils::error_other("usb write failed".to_string()))
} else {
Ok(ret)
}
}
}
type BridgeWriter_ = Arc<Mutex<BridgeWriter>>;
type BridgeMap_ = Arc<RwLock<HashMap<u32, BridgeWriter_>>>;
pub struct BridgeMap {}
impl BridgeMap {
fn get_instance() -> BridgeMap_ {
static mut BRIDGE_MAP: Option<BridgeMap_> = None;
unsafe {
BRIDGE_MAP
.get_or_insert_with(|| Arc::new(RwLock::new(HashMap::new())))
.clone()
}
}
pub async fn put(session_id: u32, data: TaskMessage) {
let send = serializer::concat_pack(data);
let instance = Self::get_instance();
let map = instance.read().await;
let Some(arc_wr) = map.get(&session_id) else {
return;
};
let wr = arc_wr.lock().await;
let _ = wr.write_all(send);
}
pub async fn send_channel_message(channel_id: u32, buf: Vec<u8>) -> io::Result<()> {
crate::trace!(
"send channel msg: {:?}",
buf.iter()
.map(|&c| format!("{c:02X}"))
.collect::<Vec<_>>()
.join(" ")
);
let send = [
u32::to_be_bytes(buf.len() as u32).as_slice(),
buf.as_slice(),
]
.concat();
let instance = Self::get_instance();
let map = instance.read().await;
if let Some(guard) = map.get(&channel_id) {
let wr = guard.lock().await;
let _ = wr.write_all(send);
return Ok(());
}
Err(Error::new(ErrorKind::NotFound, "channel not found"))
}
pub async fn start(id: u32, wr: BridgeWriter) {
let instance = Self::get_instance();
let mut map = instance.write().await;
let arc_wr = Arc::new(Mutex::new(wr));
map.insert(id, arc_wr);
ConnectTypeMap::put(id, ConnectType::Bridge).await;
}
pub async fn end(id: u32) {
let instance = Self::get_instance();
let mut map = instance.write().await;
if let Some(arc_wr) = map.remove(&id) {
let mut _wr = arc_wr.lock().await;
}
}
}