1use {
2 crate::{
3 header::{ControlMessageType, DataMessageType, Header, MessageType},
4 pdo::{
5 AugmentedPowerDataObject, AugmentedPowerDataObjectRaw, Battery,
6 EPRAdjustableVoltageSupply, FixedSupply, PowerDataObject, PowerDataObjectRaw,
7 SPRProgrammablePowerSupply, VariableSupply,
8 },
9 },
10 byteorder::{ByteOrder, LittleEndian},
11 defmt::{warn, Format},
12 heapless::Vec,
13};
14
15#[derive(Clone, Format)]
16pub enum Message {
17 Accept,
18 Reject,
19 Ready,
20 SourceCapabilities(Vec<PowerDataObject, 8>),
21 Unknown,
22}
23
24impl Message {
25 pub fn parse(header: Header, payload: &[u8]) -> Self {
26 match header.message_type() {
27 MessageType::Control(ControlMessageType::Accept) => Message::Accept,
28 MessageType::Control(ControlMessageType::Reject) => Message::Reject,
29 MessageType::Control(ControlMessageType::PsRdy) => Message::Ready,
30 MessageType::Data(DataMessageType::SourceCapabilities) => Message::SourceCapabilities(
31 payload
32 .chunks_exact(4)
33 .take(header.num_objects())
34 .map(|buf| PowerDataObjectRaw(LittleEndian::read_u32(buf)))
35 .map(|pdo| match pdo.kind() {
36 0b00 => PowerDataObject::FixedSupply(FixedSupply(pdo.0)),
37 0b01 => PowerDataObject::Battery(Battery(pdo.0)),
38 0b10 => PowerDataObject::VariableSupply(VariableSupply(pdo.0)),
39 0b11 => PowerDataObject::AugmentedPowerDataObject({
40 match AugmentedPowerDataObjectRaw(pdo.0).supply() {
41 0b00 => {
42 AugmentedPowerDataObject::SPR(SPRProgrammablePowerSupply(pdo.0))
43 }
44 0b01 => {
45 AugmentedPowerDataObject::EPR(EPRAdjustableVoltageSupply(pdo.0))
46 }
47 _ => unreachable!(),
48 }
49 }),
50 _ => unreachable!(),
51 })
52 .collect(),
53 ),
54 _ => {
55 warn!("unknown message type");
56 Message::Unknown
57 }
58 }
59 }
60}