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