rsiot/components/cmp_linux_can/
can_settings.rs1use tracing::info;
2
3use super::{CanSettings, CanSettingsBitrate, CanSettingsDbitrate};
4
5impl CanSettings {
6 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}