use std::net::Ipv4Addr;
use crate::event::Event;
use crate::state::State;
use crate::types::{V2ipPrivacy, V2ipPrivacyStream};
use crate::wire::UID_LEN;
use super::handlers::{u16_at, u32_at};
use super::Rx;
const PRIVACY_HEADER_SIZE: usize = UID_LEN + 4;
const PRIVACY_REPORT: u8 = 0;
const PRIVACY_STREAMS: usize = 3;
const PRIVACY_STREAM_SIZE: usize = 48;
pub(super) fn privacy(state: &mut State, rx: &Rx<'_>, ev: &mut Vec<Event>) {
let p = rx.frame.payload();
let len = PRIVACY_HEADER_SIZE + PRIVACY_STREAMS * PRIVACY_STREAM_SIZE;
if p.len() < len
|| p[UID_LEN] != PRIVACY_REPORT
|| usize::from(p[UID_LEN + 1]) < PRIVACY_STREAMS
{
return;
}
let at = |i: usize| stream(&p[PRIVACY_HEADER_SIZE + i * PRIVACY_STREAM_SIZE..]);
let privacy = V2ipPrivacy {
video: at(0),
audio: at(1),
anc: at(2),
};
if let Some(device) = state.device_mut(rx.sender()) {
device.set_v2ip_privacy(privacy, ev);
}
}
fn stream(s: &[u8]) -> V2ipPrivacyStream {
V2ipPrivacyStream {
group: Ipv4Addr::new(s[0], s[1], s[2], s[3]),
port: u16_at(s, 4),
version: s[6],
on: s[8] != 0,
full_id: s[9],
short_id: s[10],
iv: octets(&s[11..]),
key_generator: octets(&s[19..]),
key_id: octets(&s[35..]),
key_version: u32_at(s, 43),
}
}
fn octets<const N: usize>(s: &[u8]) -> [u8; N] {
let mut out = [0; N];
out.copy_from_slice(&s[..N]);
out
}