1use umsh_core::{PacketType, PayloadType};
2
3use crate::{AppParseError, MacCommand, NodeIdentityPayload, identity, mac_command};
4
5pub fn split_payload_type(payload: &[u8]) -> Result<(PayloadType, &[u8]), AppParseError> {
6 if payload.is_empty() {
7 return Ok((PayloadType::Empty, &[]));
8 }
9 if let Some(payload_type) = PayloadType::from_byte(payload[0]) {
10 Ok((payload_type, &payload[1..]))
11 } else {
12 Ok((PayloadType::Empty, payload))
13 }
14}
15
16pub fn expect_payload_type(
17 packet_type: PacketType,
18 payload: &[u8],
19 expected: PayloadType,
20) -> Result<&[u8], AppParseError> {
21 let (payload_type, body) = split_payload_type(payload)?;
22 if !payload_type.allowed_for(packet_type) {
23 return Err(AppParseError::PayloadTypeNotAllowed {
24 payload_type: payload_type as u8,
25 packet_type,
26 });
27 }
28 if payload_type != expected {
29 return Err(AppParseError::InvalidPayloadType(payload_type as u8));
30 }
31 Ok(body)
32}
33
34pub fn parse_mac_command_payload(
35 packet_type: PacketType,
36 payload: &[u8],
37) -> Result<MacCommand<'_>, AppParseError> {
38 mac_command::parse(expect_payload_type(
39 packet_type,
40 payload,
41 PayloadType::MacCommand,
42 )?)
43}
44
45pub fn parse_node_identity_payload(
46 packet_type: PacketType,
47 payload: &[u8],
48) -> Result<NodeIdentityPayload<'_>, AppParseError> {
49 identity::parse(expect_payload_type(
50 packet_type,
51 payload,
52 PayloadType::NodeIdentity,
53 )?)
54}