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//! uart 16#![allow(missing_docs)] 17 18use super::base; 19 20use super::uart_wrapper; 21use crate::config; 22use crate::serializer; 23#[allow(unused)] 24use crate::serializer::native_struct::UartHead; 25use crate::serializer::serialize::Serialization; 26use crate::serializer::serialize::SerializedBuffer; 27use crate::utils; 28#[allow(unused)] 29use crate::utils::hdc_log::*; 30 31#[cfg(not(target_os = "windows"))] 32use std::ffi::CString; 33use std::io::{self, Error, ErrorKind}; 34 35#[cfg(feature = "host")] 36extern crate ylong_runtime_static as ylong_runtime; 37use ylong_runtime::task::JoinHandle; 38 39#[allow(unused)] 40extern "C" { 41 fn access(_name: *const libc::c_char, _type: i32) -> i32; 42 fn free(ptr: *const libc::c_void); 43 44 #[cfg(not(target_os = "windows"))] 45 fn GetUartSpeedExt(speed: i32) -> i32; 46 #[cfg(not(target_os = "windows"))] 47 fn GetUartBitsExt(bits: i32) -> i32; 48 fn OpenSerialPortExt(port: *const libc::c_char) -> i32; 49 fn SetSerialExt(fd: i32, speed: i32, bits: i32, event: u8, stop: i32) -> i32; 50 fn ReadUartDevExt(fd: i32, size: i32) -> SerializedBuffer; 51 fn WriteUartDevExt(fd: i32, buf: SerializedBuffer) -> i32; 52 fn CloseSerialPortExt(fd: i32) -> u8; 53} 54 55#[cfg(not(target_os = "windows"))] 56pub fn uart_init() -> io::Result<i32> { 57 let name = CString::new(config::UART_NODE).unwrap(); 58 let fd = unsafe { 59 if access(name.as_ptr(), 0) != 0 { 60 return Err(utils::error_other("cannot access uart node".to_string())); 61 } 62 let fd = OpenSerialPortExt(name.as_ptr()); 63 if fd < 0 { 64 return Err(utils::error_other("cannot open uart node".to_string())); 65 } 66 if SetSerialExt( 67 fd, 68 config::UART_DEFAULT_BAUD_RATE, 69 config::UART_DEFAULT_BITS, 70 config::UART_EVENT, 71 1, 72 ) != 0 73 { 74 return Err(utils::error_other("set uart config failed".to_string())); 75 } 76 crate::debug!("uart init fd: {fd}"); 77 fd 78 }; 79 Ok(fd) 80} 81 82pub fn uart_close(_fd: i32) { 83 #[cfg(not(target_os = "windows"))] 84 unsafe { 85 CloseSerialPortExt(_fd); 86 } 87 #[cfg(target_os = "windows")] 88 return {}; 89} 90 91pub struct UartReader { 92 pub fd: i32, 93 pub head: Option<UartHead>, 94} 95 96pub struct UartWriter { 97 pub fd: i32, 98} 99 100impl base::Reader for UartReader { 101 fn read_frame(&self, expected_size: usize) -> io::Result<Vec<u8>> { 102 if expected_size == 0 { 103 return Ok(vec![]); 104 } 105 let mut data = vec![]; 106 let mut index = 0; 107 while index < expected_size { 108 crate::trace!("before read {index} / {expected_size}"); 109 let buf = unsafe { 110 let recv = ReadUartDevExt(self.fd, (expected_size - index) as i32); 111 let slice = std::slice::from_raw_parts( 112 recv.ptr as *const libc::c_uchar, 113 recv.size as usize, 114 ); 115 index += recv.size as usize; 116 slice.to_vec() 117 }; 118 data = [data, buf].concat(); 119 } 120 Ok(data) 121 } 122 123 fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> { 124 let buf = self.read_frame(serializer::UART_HEAD_SIZE)?; 125 if buf[..config::PACKET_FLAG.len()] != config::PACKET_FLAG[..] { 126 return Err(Error::new( 127 ErrorKind::Other, 128 format!("uart PACKET_FLAG incorrect, content: {:#?}", buf), 129 )); 130 } 131 let mut head = serializer::native_struct::UartHead::default(); 132 133 if let Err(e) = head.parse(buf) { 134 log::warn!("parse uart head error: {}", e.to_string()); 135 return Err(e); 136 } 137 138 self.head = Some(head.clone()); 139 140 Ok((head.data_size, head.package_index, head.session_id)) 141 } 142 143 #[allow(unused)] 144 fn process_head(&self) -> Option<JoinHandle<()>> { 145 let head = self.head.clone(); 146 if let Some(head) = head { 147 let join_handle = utils::spawn(async move { 148 uart_wrapper::on_read_head(head).await; 149 }); 150 Some(join_handle) 151 } else { 152 None 153 } 154 } 155} 156 157impl base::Writer for UartWriter { 158 fn write_all(&self, data: Vec<u8>) -> io::Result<i32> { 159 let buf = SerializedBuffer { 160 ptr: data.as_ptr() as *const libc::c_char, 161 size: data.len() as u64, 162 }; 163 crate::debug!("write all start, fd:{}...", self.fd); 164 let write_count = unsafe { WriteUartDevExt(self.fd, buf) } as i32; 165 crate::debug!("write count:{}", write_count); 166 if write_count < 0 { 167 Err(utils::error_other("uart write failed".to_string())) 168 } else { 169 Ok(write_count) 170 } 171 } 172} 173 174pub fn build_header(session_id: u32, option: u16, length: usize, package_index: u32) -> Vec<u8> { 175 UartHead { 176 session_id: u32::to_le(session_id), 177 flag: [config::PACKET_FLAG[0], config::PACKET_FLAG[1]], 178 option, 179 data_size: u32::to_le(length as u32), 180 package_index, 181 data_checksum: 0, 182 head_checksum: 0, 183 } 184 .serialize() 185} 186 187pub fn build_header_obj( 188 session_id: u32, 189 option: u16, 190 length: usize, 191 package_index: u32, 192) -> UartHead { 193 UartHead { 194 session_id: u32::to_le(session_id), 195 flag: [config::PACKET_FLAG[0], config::PACKET_FLAG[1]], 196 option, 197 data_size: u32::to_le(length as u32), 198 package_index, 199 data_checksum: 0, 200 head_checksum: 0, 201 } 202} 203