Skip to main content

rsiot/components/cmp_linux_can/
can_settings.rs

1use tracing::info;
2
3use super::{CanSettings, CanSettingsBitrate, CanSettingsDbitrate};
4
5impl CanSettings {
6    /// Преобразование настроек CAN в команду для ip link
7    pub fn into_ip_link_command(&self, ifname: &str) -> Vec<String> {
8        let mut command = CommandBuilder::new();
9
10        command.push("ip");
11        command.push("link");
12        command.push("set");
13
14        command.push(ifname);
15
16        command.push("type");
17        command.push("can");
18
19        match self.bitrate {
20            CanSettingsBitrate::Standard {
21                bitrate,
22                sample_point,
23            } => {
24                command.push("bitrate");
25                command.push(bitrate);
26
27                if let Some(sample_point) = sample_point {
28                    command.push("sample-point");
29                    command.push(sample_point);
30                }
31            }
32            CanSettingsBitrate::Custom {
33                tq,
34                prop_seg,
35                phase_seg1,
36                phase_seg2,
37                sjw,
38            } => {
39                command.push("tq");
40                command.push(tq);
41
42                command.push("prop-seg");
43                command.push(prop_seg);
44
45                command.push("phase-seg1");
46                command.push(phase_seg1);
47
48                command.push("phase-seg2");
49                command.push(phase_seg2);
50
51                if let Some(sjw) = sjw {
52                    command.push("sjw");
53                    command.push(sjw);
54                }
55            }
56        }
57
58        match self.dbitrate {
59            CanSettingsDbitrate::None => (),
60            CanSettingsDbitrate::Standard {
61                dbitrate,
62                dsample_point,
63                tdcv: _,
64                tdco: _,
65                tdcf: _,
66            } => {
67                command.push("dbitrate");
68                command.push(dbitrate);
69
70                if let Some(dsample_point) = dsample_point {
71                    command.push("dsample-point");
72                    command.push(dsample_point);
73                }
74            }
75            CanSettingsDbitrate::Custom {
76                dtq: _,
77                dprop_seg: _,
78                dphase_seg1: _,
79                dphase_seg2: _,
80                dsjw: _,
81                tdcv: _,
82                tdco: _,
83                tdcf: _,
84            } => unimplemented!(),
85        }
86
87        command.push("loopback");
88        command.push(mode_on_off(self.mode_loopback));
89
90        command.push("listen-only");
91        command.push(mode_on_off(self.mode_listen_only));
92
93        command.push("triple-sampling");
94        command.push(mode_on_off(self.mode_triple_sampling));
95
96        command.push("one-shot");
97        command.push(mode_on_off(self.mode_one_shot));
98
99        command.push("berr-reporting");
100        command.push(mode_on_off(self.mode_berr_reporting));
101
102        command.push("fd");
103        command.push(mode_on_off(self.mode_fd));
104
105        command.push("fd-non-iso");
106        command.push(mode_on_off(self.mode_fd_non_iso));
107
108        command.push("presume-ack");
109        command.push(mode_on_off(self.mode_presume_ack));
110
111        command.push("cc-len8-dlc");
112        command.push(mode_on_off(self.mode_cc_len8_dlc));
113
114        if let Some(restart_ms) = self.restart_ms {
115            command.push("restart-ms");
116            command.push(restart_ms);
117        }
118
119        info!("CAN setup command: {:?}", command.join());
120
121        command.build()
122    }
123}
124
125struct CommandBuilder(Vec<String>);
126impl CommandBuilder {
127    fn new() -> Self {
128        CommandBuilder(Vec::new())
129    }
130    fn push(&mut self, arg: impl ToString) {
131        self.0.push(arg.to_string());
132    }
133    fn join(&self) -> String {
134        self.0.join(" ")
135    }
136    fn build(self) -> Vec<String> {
137        self.0
138    }
139}
140
141fn mode_on_off(mode: bool) -> &'static str {
142    if mode { "on" } else { "off" }
143}