Skip to main content

starnix_uapi/
termios.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::uapi;
6
7// Note: The uapi::BXXX constants (e.g., B9600) do not have the same values as the baud rates
8// they represent (e.g., 9600). For example, B9600 is 13. Therefore, we need these conversion
9// functions to map between the numerical baud rates (used in c_ispeed/c_ospeed) and the
10// c_cflag bitmasks.
11
12pub fn into_termios2(value: uapi::termio) -> uapi::termios2 {
13    let mut cc = [0; 19];
14    cc[0..8].copy_from_slice(&value.c_cc[0..8]);
15    let c_cflag = value.c_cflag as uapi::tcflag_t;
16    let speed = cbaud_to_speed(c_cflag & uapi::CBAUD);
17    uapi::termios2 {
18        c_iflag: value.c_iflag as uapi::tcflag_t,
19        c_oflag: value.c_oflag as uapi::tcflag_t,
20        c_cflag,
21        c_lflag: value.c_lflag as uapi::tcflag_t,
22        c_line: value.c_line as uapi::cc_t,
23        c_cc: cc,
24        c_ispeed: speed,
25        c_ospeed: speed,
26    }
27}
28
29pub fn into_termio(value: &uapi::termios2) -> uapi::termio {
30    let mut cc = [0; 8];
31    cc.copy_from_slice(&value.c_cc[0..8]);
32    uapi::termio {
33        c_iflag: value.c_iflag as u16,
34        c_oflag: value.c_oflag as u16,
35        c_cflag: value.c_cflag as u16,
36        c_lflag: value.c_lflag as u16,
37        c_line: value.c_line,
38        c_cc: cc,
39        ..Default::default()
40    }
41}
42
43pub fn termios2_from_termios(value: &uapi::termios) -> uapi::termios2 {
44    let cbaud = value.c_cflag & uapi::CBAUD;
45    let speed = cbaud_to_speed(cbaud);
46    uapi::termios2 {
47        c_iflag: value.c_iflag,
48        c_oflag: value.c_oflag,
49        c_cflag: value.c_cflag,
50        c_lflag: value.c_lflag,
51        c_line: value.c_line,
52        c_cc: value.c_cc,
53        c_ispeed: speed,
54        c_ospeed: speed,
55    }
56}
57
58pub fn termios_from_termios2(value: &uapi::termios2) -> uapi::termios {
59    let mut c_cflag = value.c_cflag;
60    if let Some(cbaud) = speed_to_cbaud(value.c_ospeed) {
61        c_cflag = (c_cflag & !uapi::CBAUD) | cbaud;
62    }
63    uapi::termios {
64        c_iflag: value.c_iflag,
65        c_oflag: value.c_oflag,
66        c_cflag,
67        c_lflag: value.c_lflag,
68        c_line: value.c_line,
69        c_cc: value.c_cc,
70    }
71}
72
73pub fn speed_to_cbaud(speed: u32) -> Option<uapi::tcflag_t> {
74    match speed {
75        0 => Some(uapi::B0),
76        50 => Some(uapi::B50),
77        75 => Some(uapi::B75),
78        110 => Some(uapi::B110),
79        134 => Some(uapi::B134),
80        150 => Some(uapi::B150),
81        200 => Some(uapi::B200),
82        300 => Some(uapi::B300),
83        600 => Some(uapi::B600),
84        1200 => Some(uapi::B1200),
85        1800 => Some(uapi::B1800),
86        2400 => Some(uapi::B2400),
87        4800 => Some(uapi::B4800),
88        9600 => Some(uapi::B9600),
89        19200 => Some(uapi::B19200),
90        38400 => Some(uapi::B38400),
91        57600 => Some(uapi::B57600),
92        115200 => Some(uapi::B115200),
93        230400 => Some(uapi::B230400),
94        460800 => Some(uapi::B460800),
95        500000 => Some(uapi::B500000),
96        576000 => Some(uapi::B576000),
97        921600 => Some(uapi::B921600),
98        1000000 => Some(uapi::B1000000),
99        1152000 => Some(uapi::B1152000),
100        1500000 => Some(uapi::B1500000),
101        2000000 => Some(uapi::B2000000),
102        2500000 => Some(uapi::B2500000),
103        3000000 => Some(uapi::B3000000),
104        3500000 => Some(uapi::B3500000),
105        4000000 => Some(uapi::B4000000),
106        _ => Some(uapi::BOTHER),
107    }
108}
109
110pub fn cbaud_to_speed(cbaud: uapi::tcflag_t) -> u32 {
111    match cbaud {
112        uapi::B0 => 0,
113        uapi::B50 => 50,
114        uapi::B75 => 75,
115        uapi::B110 => 110,
116        uapi::B134 => 134,
117        uapi::B150 => 150,
118        uapi::B200 => 200,
119        uapi::B300 => 300,
120        uapi::B600 => 600,
121        uapi::B1200 => 1200,
122        uapi::B1800 => 1800,
123        uapi::B2400 => 2400,
124        uapi::B4800 => 4800,
125        uapi::B9600 => 9600,
126        uapi::B19200 => 19200,
127        uapi::B38400 => 38400,
128        uapi::B57600 => 57600,
129        uapi::B115200 => 115200,
130        uapi::B230400 => 230400,
131        uapi::B460800 => 460800,
132        uapi::B500000 => 500000,
133        uapi::B576000 => 576000,
134        uapi::B921600 => 921600,
135        uapi::B1000000 => 1000000,
136        uapi::B1152000 => 1152000,
137        uapi::B1500000 => 1500000,
138        uapi::B2000000 => 2000000,
139        uapi::B2500000 => 2500000,
140        uapi::B3000000 => 3000000,
141        uapi::B3500000 => 3500000,
142        uapi::B4000000 => 4000000,
143        _ => 0,
144    }
145}