1 use core::{fmt::Debug, sync::atomic::Ordering};
2
3 use alloc::sync::{Arc, Weak};
4 use kdepends::thingbuf::mpsc;
5 use system_error::SystemError;
6
7 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
8
9 use super::{
10 tty_core::TtyCore,
11 virtual_terminal::{virtual_console::CURRENT_VCNUM, VIRT_CONSOLES},
12 };
13
14 const TTY_PORT_BUFSIZE: usize = 4096;
15
16 /// 获取当前tty port
17 #[inline]
current_tty_port() -> Arc<dyn TtyPort>18 pub fn current_tty_port() -> Arc<dyn TtyPort> {
19 VIRT_CONSOLES[CURRENT_VCNUM.load(Ordering::SeqCst) as usize]
20 .lock_irqsave()
21 .port()
22 }
23
24 #[inline]
tty_port(index: usize) -> Arc<dyn TtyPort>25 pub fn tty_port(index: usize) -> Arc<dyn TtyPort> {
26 VIRT_CONSOLES[index].lock_irqsave().port()
27 }
28
29 #[allow(dead_code)]
30 #[derive(Debug)]
31 pub struct TtyPortData {
32 flags: i32,
33 iflags: TtyPortState,
34 sender: mpsc::Sender<u8>,
35 receiver: mpsc::Receiver<u8>,
36 tty: Weak<TtyCore>,
37 /// 内部tty,即与port直接相连的
38 internal_tty: Weak<TtyCore>,
39 }
40
41 impl Default for TtyPortData {
default() -> Self42 fn default() -> Self {
43 Self::new()
44 }
45 }
46
47 impl TtyPortData {
new() -> Self48 pub fn new() -> Self {
49 let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE);
50 Self {
51 flags: 0,
52 iflags: TtyPortState::Initialized,
53 sender,
54 receiver,
55 tty: Weak::new(),
56 internal_tty: Weak::new(),
57 }
58 }
59
internal_tty(&self) -> Option<Arc<TtyCore>>60 pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
61 self.internal_tty.upgrade()
62 }
63
tty(&self) -> Option<Arc<TtyCore>>64 pub fn tty(&self) -> Option<Arc<TtyCore>> {
65 self.tty.upgrade()
66 }
67 }
68
69 #[allow(dead_code)]
70 #[derive(Debug, PartialEq, Clone, Copy)]
71 pub enum TtyPortState {
72 Initialized,
73 Suspended,
74 Active,
75 CtsFlow,
76 CheckCD,
77 KOPENED,
78 }
79
80 pub trait TtyPort: Sync + Send + Debug {
port_data(&self) -> SpinLockGuard<TtyPortData>81 fn port_data(&self) -> SpinLockGuard<TtyPortData>;
82
83 /// 获取Port的状态
state(&self) -> TtyPortState84 fn state(&self) -> TtyPortState {
85 self.port_data().iflags
86 }
87
88 /// 为port设置tty
setup_internal_tty(&self, tty: Weak<TtyCore>)89 fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
90 self.port_data().internal_tty = tty;
91 }
92
93 /// 作为客户端的tty ports接收数据
receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError>94 fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
95 let tty = self.port_data().internal_tty().unwrap();
96
97 let ld = tty.ldisc();
98
99 let ret = ld.receive_buf2(tty.clone(), buf, None, count);
100 if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS {
101 return ld.receive_buf(tty, buf, None, count);
102 }
103
104 ret
105 }
106 }
107
108 #[derive(Debug)]
109 pub struct DefaultTtyPort {
110 port_data: SpinLock<TtyPortData>,
111 }
112
113 impl DefaultTtyPort {
new() -> Self114 pub fn new() -> Self {
115 Self {
116 port_data: SpinLock::new(TtyPortData::new()),
117 }
118 }
119 }
120
121 impl TtyPort for DefaultTtyPort {
port_data(&self) -> SpinLockGuard<TtyPortData>122 fn port_data(&self) -> SpinLockGuard<TtyPortData> {
123 self.port_data.lock_irqsave()
124 }
125 }
126