1use crate::tlv;
7use anyhow;
8
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
13#[repr(u8)]
14pub enum CecKeyCode {
15 Select = 0,
16 Up = 1,
17 Down = 2,
18 Left = 3,
19 Right = 4,
20 Rightup = 5,
21 Rightdown = 6,
22 Leftup = 7,
23 Leftdown = 8,
24 Rootmenu = 9,
25 Setupmenu = 10,
26 Contentsmenu = 11,
27 Favoritemenu = 12,
28 Exit = 13,
29 Mediatopmenu = 16,
30 Mediacontextsensitivemenu = 17,
31 Numberentrymode = 29,
32 Number11 = 30,
33 Number12 = 31,
34 Number0ornumber10 = 32,
35 Numbers1 = 33,
36 Numbers2 = 34,
37 Numbers3 = 35,
38 Numbers4 = 36,
39 Numbers5 = 37,
40 Numbers6 = 38,
41 Numbers7 = 39,
42 Numbers8 = 40,
43 Numbers9 = 41,
44 Dot = 42,
45 Enter = 43,
46 Clear = 44,
47 Nextfavorite = 47,
48 Channelup = 48,
49 Channeldown = 49,
50 Previouschannel = 50,
51 Soundselect = 51,
52 Inputselect = 52,
53 Displayinformation = 53,
54 Help = 54,
55 Pageup = 55,
56 Pagedown = 56,
57 Power = 64,
58 Volumeup = 65,
59 Volumedown = 66,
60 Mute = 67,
61 Play = 68,
62 Stop = 69,
63 Pause = 70,
64 Record = 71,
65 Rewind = 72,
66 Fastforward = 73,
67 Eject = 74,
68 Forward = 75,
69 Backward = 76,
70 Stoprecord = 77,
71 Pauserecord = 78,
72 Reserved = 79,
73 Angle = 80,
74 Subpicture = 81,
75 Videoondemand = 82,
76 Electronicprogramguide = 83,
77 Timerprogramming = 84,
78 Initialconfiguration = 85,
79 Selectbroadcasttype = 86,
80 Selectsoundpresentation = 87,
81 Playfunction = 96,
82 Pauseplayfunction = 97,
83 Recordfunction = 98,
84 Pauserecordfunction = 99,
85 Stopfunction = 100,
86 Mutefunction = 101,
87 Restorevolumefunction = 102,
88 Tunefunction = 103,
89 Selectmediafunction = 104,
90 Selectavinputfunction = 105,
91 Selectaudioinputfunction = 106,
92 Powertogglefunction = 107,
93 Powerofffunction = 108,
94 Poweronfunction = 109,
95 F1blue = 113,
96 F2red = 114,
97 F3green = 115,
98 F4yellow = 116,
99 F5 = 117,
100 Data = 118,
101}
102
103impl CecKeyCode {
104 pub fn from_u8(value: u8) -> Option<Self> {
106 match value {
107 0 => Some(CecKeyCode::Select),
108 1 => Some(CecKeyCode::Up),
109 2 => Some(CecKeyCode::Down),
110 3 => Some(CecKeyCode::Left),
111 4 => Some(CecKeyCode::Right),
112 5 => Some(CecKeyCode::Rightup),
113 6 => Some(CecKeyCode::Rightdown),
114 7 => Some(CecKeyCode::Leftup),
115 8 => Some(CecKeyCode::Leftdown),
116 9 => Some(CecKeyCode::Rootmenu),
117 10 => Some(CecKeyCode::Setupmenu),
118 11 => Some(CecKeyCode::Contentsmenu),
119 12 => Some(CecKeyCode::Favoritemenu),
120 13 => Some(CecKeyCode::Exit),
121 16 => Some(CecKeyCode::Mediatopmenu),
122 17 => Some(CecKeyCode::Mediacontextsensitivemenu),
123 29 => Some(CecKeyCode::Numberentrymode),
124 30 => Some(CecKeyCode::Number11),
125 31 => Some(CecKeyCode::Number12),
126 32 => Some(CecKeyCode::Number0ornumber10),
127 33 => Some(CecKeyCode::Numbers1),
128 34 => Some(CecKeyCode::Numbers2),
129 35 => Some(CecKeyCode::Numbers3),
130 36 => Some(CecKeyCode::Numbers4),
131 37 => Some(CecKeyCode::Numbers5),
132 38 => Some(CecKeyCode::Numbers6),
133 39 => Some(CecKeyCode::Numbers7),
134 40 => Some(CecKeyCode::Numbers8),
135 41 => Some(CecKeyCode::Numbers9),
136 42 => Some(CecKeyCode::Dot),
137 43 => Some(CecKeyCode::Enter),
138 44 => Some(CecKeyCode::Clear),
139 47 => Some(CecKeyCode::Nextfavorite),
140 48 => Some(CecKeyCode::Channelup),
141 49 => Some(CecKeyCode::Channeldown),
142 50 => Some(CecKeyCode::Previouschannel),
143 51 => Some(CecKeyCode::Soundselect),
144 52 => Some(CecKeyCode::Inputselect),
145 53 => Some(CecKeyCode::Displayinformation),
146 54 => Some(CecKeyCode::Help),
147 55 => Some(CecKeyCode::Pageup),
148 56 => Some(CecKeyCode::Pagedown),
149 64 => Some(CecKeyCode::Power),
150 65 => Some(CecKeyCode::Volumeup),
151 66 => Some(CecKeyCode::Volumedown),
152 67 => Some(CecKeyCode::Mute),
153 68 => Some(CecKeyCode::Play),
154 69 => Some(CecKeyCode::Stop),
155 70 => Some(CecKeyCode::Pause),
156 71 => Some(CecKeyCode::Record),
157 72 => Some(CecKeyCode::Rewind),
158 73 => Some(CecKeyCode::Fastforward),
159 74 => Some(CecKeyCode::Eject),
160 75 => Some(CecKeyCode::Forward),
161 76 => Some(CecKeyCode::Backward),
162 77 => Some(CecKeyCode::Stoprecord),
163 78 => Some(CecKeyCode::Pauserecord),
164 79 => Some(CecKeyCode::Reserved),
165 80 => Some(CecKeyCode::Angle),
166 81 => Some(CecKeyCode::Subpicture),
167 82 => Some(CecKeyCode::Videoondemand),
168 83 => Some(CecKeyCode::Electronicprogramguide),
169 84 => Some(CecKeyCode::Timerprogramming),
170 85 => Some(CecKeyCode::Initialconfiguration),
171 86 => Some(CecKeyCode::Selectbroadcasttype),
172 87 => Some(CecKeyCode::Selectsoundpresentation),
173 96 => Some(CecKeyCode::Playfunction),
174 97 => Some(CecKeyCode::Pauseplayfunction),
175 98 => Some(CecKeyCode::Recordfunction),
176 99 => Some(CecKeyCode::Pauserecordfunction),
177 100 => Some(CecKeyCode::Stopfunction),
178 101 => Some(CecKeyCode::Mutefunction),
179 102 => Some(CecKeyCode::Restorevolumefunction),
180 103 => Some(CecKeyCode::Tunefunction),
181 104 => Some(CecKeyCode::Selectmediafunction),
182 105 => Some(CecKeyCode::Selectavinputfunction),
183 106 => Some(CecKeyCode::Selectaudioinputfunction),
184 107 => Some(CecKeyCode::Powertogglefunction),
185 108 => Some(CecKeyCode::Powerofffunction),
186 109 => Some(CecKeyCode::Poweronfunction),
187 113 => Some(CecKeyCode::F1blue),
188 114 => Some(CecKeyCode::F2red),
189 115 => Some(CecKeyCode::F3green),
190 116 => Some(CecKeyCode::F4yellow),
191 117 => Some(CecKeyCode::F5),
192 118 => Some(CecKeyCode::Data),
193 _ => None,
194 }
195 }
196
197 pub fn to_u8(self) -> u8 {
199 self as u8
200 }
201}
202
203impl From<CecKeyCode> for u8 {
204 fn from(val: CecKeyCode) -> Self {
205 val as u8
206 }
207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
210#[repr(u8)]
211pub enum Status {
212 Success = 0,
214 Unsupportedkey = 1,
216 Invalidkeyincurrentstate = 2,
218}
219
220impl Status {
221 pub fn from_u8(value: u8) -> Option<Self> {
223 match value {
224 0 => Some(Status::Success),
225 1 => Some(Status::Unsupportedkey),
226 2 => Some(Status::Invalidkeyincurrentstate),
227 _ => None,
228 }
229 }
230
231 pub fn to_u8(self) -> u8 {
233 self as u8
234 }
235}
236
237impl From<Status> for u8 {
238 fn from(val: Status) -> Self {
239 val as u8
240 }
241}
242
243pub fn encode_send_key(key_code: CecKeyCode) -> anyhow::Result<Vec<u8>> {
247 let tlv = tlv::TlvItemEnc {
248 tag: 0,
249 value: tlv::TlvItemValueEnc::StructInvisible(vec![
250 (0, tlv::TlvItemValueEnc::UInt8(key_code.to_u8())).into(),
251 ]),
252 };
253 Ok(tlv.encode()?)
254}
255
256#[derive(Debug, serde::Serialize)]
257pub struct SendKeyResponse {
258 pub status: Option<Status>,
259}
260
261pub fn decode_send_key_response(inp: &tlv::TlvItemValue) -> anyhow::Result<SendKeyResponse> {
265 if let tlv::TlvItemValue::List(_fields) = inp {
266 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
267 Ok(SendKeyResponse {
268 status: item.get_int(&[0]).and_then(|v| Status::from_u8(v as u8)),
269 })
270 } else {
271 Err(anyhow::anyhow!("Expected struct fields"))
272 }
273}
274