use crate::dummy::{DUMMY_EPR_SOURCE_CAPS_CHUNK_0, DUMMY_EPR_SOURCE_CAPS_CHUNK_1};
use crate::protocol_layer::message::data::Data;
use crate::protocol_layer::message::data::epr_mode::Action;
use crate::protocol_layer::message::data::request::PowerSource;
use crate::protocol_layer::message::extended::Extended;
use crate::protocol_layer::message::extended::chunked::{ChunkResult, ChunkedMessageAssembler};
use crate::protocol_layer::message::header::{DataMessageType, ExtendedMessageType, MessageType};
use crate::protocol_layer::message::{Message, Payload};
const EPR_MODE_ENTER: &[u8] = &[0x8A, 0x14, 0x00, 0x00, 0x00, 0x01];
const EPR_MODE_ENTER_ACK: &[u8] = &[0xAA, 0x19, 0x00, 0x00, 0x00, 0x02];
const EPR_MODE_ENTER_SUCCEEDED: &[u8] = &[0xAA, 0x1B, 0x00, 0x00, 0x00, 0x03];
const EPR_REQUEST_28V: &[u8] = &[0x89, 0x28, 0xF4, 0xD1, 0xC7, 0x80, 0xF4, 0xC1, 0x18, 0x00];
const EPR_KEEP_ALIVE: &[u8] = &[0x90, 0x9A, 0x02, 0x80, 0x03, 0x00];
#[test]
fn test_epr_mode_messages() {
let enter = Message::from_bytes(EPR_MODE_ENTER).expect("Failed to parse EPR_MODE_ENTER");
assert_eq!(enter.header.message_type(), MessageType::Data(DataMessageType::EprMode));
if let Some(Payload::Data(Data::EprMode(mode))) = enter.payload {
assert_eq!(mode.action(), Action::Enter);
} else {
panic!("Expected EprMode Enter payload");
}
let ack = Message::from_bytes(EPR_MODE_ENTER_ACK).expect("Failed to parse EPR_MODE_ENTER_ACK");
if let Some(Payload::Data(Data::EprMode(mode))) = ack.payload {
assert_eq!(mode.action(), Action::EnterAcknowledged);
} else {
panic!("Expected EprMode EnterAcknowledged payload");
}
let success = Message::from_bytes(EPR_MODE_ENTER_SUCCEEDED).expect("Failed to parse EPR_MODE_ENTER_SUCCEEDED");
if let Some(Payload::Data(Data::EprMode(mode))) = success.payload {
assert_eq!(mode.action(), Action::EnterSucceeded);
} else {
panic!("Expected EprMode EnterSucceeded payload");
}
}
#[test]
fn test_chunked_epr_source_caps_assembly() {
let mut assembler = ChunkedMessageAssembler::new();
let (header_0, ext_header_0, chunk_data_0) =
Message::parse_extended_chunk(&DUMMY_EPR_SOURCE_CAPS_CHUNK_0).expect("Failed to parse chunk 0");
match assembler
.process_chunk(header_0, ext_header_0, chunk_data_0)
.expect("Failed to process chunk 0")
{
ChunkResult::NeedMoreChunks(next) => {
assert_eq!(next, 1, "Should request chunk 1 next");
}
_ => panic!("Expected NeedMoreChunks after first chunk"),
}
let (header_1, ext_header_1, chunk_data_1) =
Message::parse_extended_chunk(&DUMMY_EPR_SOURCE_CAPS_CHUNK_1).expect("Failed to parse chunk 1");
match assembler
.process_chunk(header_1, ext_header_1, chunk_data_1)
.expect("Failed to process chunk 1")
{
ChunkResult::Complete(assembled_data) => {
let ext = Message::parse_extended_payload(ExtendedMessageType::EprSourceCapabilities, &assembled_data);
if let Extended::EprSourceCapabilities(pdos) = ext {
assert_eq!(pdos.len(), 10, "Expected 10 PDOs (6 SPR + 1 separator + 3 EPR)");
if let crate::protocol_layer::message::data::source_capabilities::PowerDataObject::FixedSupply(pdo) =
&pdos[6]
{
assert_eq!(pdo.0, 0, "PDO[6] should be separator (0x00000000)");
} else {
panic!("PDO[6] should be separator");
}
use uom::si::electric_potential::volt;
if let crate::protocol_layer::message::data::source_capabilities::PowerDataObject::FixedSupply(pdo) =
&pdos[7]
{
assert_eq!(pdo.voltage().get::<volt>() as f64, 28.0);
} else {
panic!("PDO[7] should be 28V EPR FixedSupply");
}
} else {
panic!("Expected EprSourceCapabilities payload");
}
}
_ => panic!("Expected Complete after second chunk"),
}
}
#[test]
fn test_epr_request_parsing() {
let msg = Message::from_bytes(EPR_REQUEST_28V).expect("Failed to parse EPR_REQUEST_28V");
assert_eq!(
msg.header.message_type(),
MessageType::Data(DataMessageType::EprRequest)
);
assert_eq!(
msg.header.num_objects(),
2,
"EPR Request should have 2 data objects (RDO + PDO)"
);
if let Some(Payload::Data(Data::Request(PowerSource::EprRequest(epr)))) = msg.payload {
assert_eq!(epr.object_position(), 8, "Should request PDO#8");
use uom::si::electric_potential::volt;
use crate::protocol_layer::message::data::source_capabilities::PowerDataObject;
if let PowerDataObject::FixedSupply(fixed) = epr.pdo {
assert_eq!(fixed.voltage().get::<volt>() as f64, 28.0);
} else {
panic!("Expected FixedSupply PDO in EprRequest");
}
} else {
panic!("Expected EprRequest payload");
}
}
#[test]
fn test_epr_keep_alive() {
let msg = Message::from_bytes(EPR_KEEP_ALIVE).expect("Failed to parse EPR_KEEP_ALIVE");
assert_eq!(
msg.header.message_type(),
MessageType::Extended(ExtendedMessageType::ExtendedControl)
);
if let Some(Payload::Extended(Extended::ExtendedControl(ctrl))) = msg.payload {
use crate::protocol_layer::message::extended::extended_control::ExtendedControlMessageType;
assert_eq!(ctrl.message_type(), ExtendedControlMessageType::EprKeepAlive);
} else {
panic!("Expected ExtendedControl EprKeepAlive payload");
}
}