use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ChannelId(pub u16);
impl ChannelId {
pub const MESSAGE: Self = Self(0);
pub const METADATA: Self = Self(1);
pub const TELEMETRY: Self = Self(2);
pub const ACK: Self = Self(3);
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ChannelHeader {
pub id: ChannelId,
pub sequence: u32,
pub payload_type: u8,
pub length: u32,
pub integrity: u32,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MultiplexedFrame {
pub channels: Vec<ChannelHeader>,
pub body: Vec<u8>,
}
impl MultiplexedFrame {
pub fn from_channels(parts: Vec<(ChannelId, u8, Vec<u8>)>) -> Self {
let mut channels = Vec::new();
let mut body = Vec::new();
for (i, (id, pty, payload)) in parts.into_iter().enumerate() {
let integrity = crate::checksum_bytes(&payload);
channels.push(ChannelHeader {
id,
sequence: i as u32,
payload_type: pty,
length: payload.len() as u32,
integrity,
});
body.extend_from_slice(&payload);
}
Self { channels, body }
}
pub fn channel_payload(&self, id: ChannelId) -> Option<&[u8]> {
let mut offset = 0usize;
for ch in &self.channels {
let end = offset + ch.length as usize;
if end > self.body.len() {
return None;
}
if ch.id == id {
return Some(&self.body[offset..end]);
}
offset = end;
}
None
}
}