wip: _top
This commit is contained in:
parent
493bf7a6e8
commit
d2f41821c0
|
@ -103,6 +103,8 @@ pub struct AtemSocket {
|
|||
socket: Option<UdpSocket>,
|
||||
address: SocketAddr,
|
||||
|
||||
protocol_version: ProtocolVersion,
|
||||
|
||||
last_received_at: SystemTime,
|
||||
last_received_packed_id: u16,
|
||||
in_flight: Vec<InFlightPacket>,
|
||||
|
@ -159,6 +161,8 @@ impl AtemSocket {
|
|||
socket: None,
|
||||
address: "0.0.0.0:0".parse().unwrap(),
|
||||
|
||||
protocol_version: ProtocolVersion::V7_2,
|
||||
|
||||
last_received_at: SystemTime::now(),
|
||||
last_received_packed_id: 0,
|
||||
in_flight: vec![],
|
||||
|
@ -532,7 +536,7 @@ impl AtemSocket {
|
|||
}
|
||||
|
||||
fn on_commands_received(&mut self, payload: &[u8]) {
|
||||
let commands = deserialize_commands(payload);
|
||||
let commands = deserialize_commands(payload, &self.protocol_version);
|
||||
|
||||
let _ = self
|
||||
.atem_event_tx
|
||||
|
|
|
@ -8,7 +8,8 @@ pub trait DeserializedCommand: Send + Sync + Debug {
|
|||
}
|
||||
|
||||
pub trait CommandDeserializer: Send + Sync {
|
||||
fn deserialize(&self, buffer: &[u8]) -> Arc<dyn DeserializedCommand>;
|
||||
fn deserialize(&self, buffer: &[u8], version: &ProtocolVersion)
|
||||
-> Arc<dyn DeserializedCommand>;
|
||||
}
|
||||
|
||||
pub trait SerializableCommand: Send + Sync {
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
pub mod product_identifier;
|
||||
pub mod topology;
|
||||
pub mod version;
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::{ffi::CString, sync::Arc};
|
|||
|
||||
use crate::{
|
||||
commands::command_base::{CommandDeserializer, DeserializedCommand},
|
||||
enums::Model,
|
||||
enums::{Model, ProtocolVersion},
|
||||
};
|
||||
|
||||
pub const DESERIALIZE_PRODUCT_IDENTIFIER_RAW_NAME: &str = "_pin";
|
||||
|
@ -43,7 +43,11 @@ impl DeserializedCommand for ProductIdentifierCommand {
|
|||
pub struct ProductIdentifierCommandDeserializer {}
|
||||
|
||||
impl CommandDeserializer for ProductIdentifierCommandDeserializer {
|
||||
fn deserialize(&self, buffer: &[u8]) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||
fn deserialize(
|
||||
&self,
|
||||
buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||
let null_byte_index = buffer
|
||||
.iter()
|
||||
.position(|byte| *byte == b'\0')
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
commands::command_base::{CommandDeserializer, DeserializedCommand},
|
||||
enums::ProtocolVersion,
|
||||
};
|
||||
|
||||
pub const DESERIALIZE_TOPOLOGY_RAW_NAME: &str = "_top";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TopologyCommand {
|
||||
mix_effects: u8,
|
||||
sources: u8,
|
||||
auxilliaries: u8,
|
||||
mix_minus_outputs: u8,
|
||||
media_players: u8,
|
||||
multiviewers: Option<u8>,
|
||||
serial_ports: u8,
|
||||
max_hyperdecks: u8,
|
||||
dves: u8,
|
||||
stingers: u8,
|
||||
super_sources: u8,
|
||||
talkback_channels: u8,
|
||||
downstream_keyers: u8,
|
||||
camera_control: bool,
|
||||
advanced_chroma_keyers: bool,
|
||||
only_configurable_outputs: bool,
|
||||
}
|
||||
|
||||
impl DeserializedCommand for TopologyCommand {
|
||||
fn raw_name(&self) -> &'static str {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TopologyCommandDeserializer {}
|
||||
|
||||
impl CommandDeserializer for TopologyCommandDeserializer {
|
||||
fn deserialize(
|
||||
&self,
|
||||
buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> std::sync::Arc<dyn crate::commands::command_base::DeserializedCommand> {
|
||||
let v230offset = if *version > ProtocolVersion::V8_0_1 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let multiviewers = if v230offset > 0 {
|
||||
Some(buffer[6])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let advanced_chroma_keyers = if buffer.len() > 20 {
|
||||
buffer[21 + v230offset] == 1
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let only_configurable_outputs = if buffer.len() > 20 {
|
||||
buffer[22 + v230offset] == 1
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Arc::new(TopologyCommand {
|
||||
mix_effects: buffer[0],
|
||||
sources: buffer[1],
|
||||
downstream_keyers: buffer[2],
|
||||
auxilliaries: buffer[3],
|
||||
mix_minus_outputs: buffer[4],
|
||||
media_players: buffer[5],
|
||||
multiviewers,
|
||||
serial_ports: buffer[6 + v230offset],
|
||||
max_hyperdecks: buffer[7 + v230offset],
|
||||
dves: buffer[8 + v230offset],
|
||||
stingers: buffer[9 + v230offset],
|
||||
super_sources: buffer[10 + v230offset],
|
||||
talkback_channels: buffer[12 + v230offset],
|
||||
camera_control: buffer[17 + v230offset] == 1,
|
||||
advanced_chroma_keyers,
|
||||
only_configurable_outputs,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -26,7 +26,11 @@ impl DeserializedCommand for VersionCommand {
|
|||
pub struct VersionCommandDeserializer {}
|
||||
|
||||
impl CommandDeserializer for VersionCommandDeserializer {
|
||||
fn deserialize(&self, buffer: &[u8]) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||
fn deserialize(
|
||||
&self,
|
||||
buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||
let version = u32::from_be_bytes([buffer[0], buffer[1], buffer[2], buffer[3]]);
|
||||
let version: ProtocolVersion = version.try_into().expect("Invalid protocol version");
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::enums::ProtocolVersion;
|
||||
|
||||
use super::command_base::{CommandDeserializer, DeserializedCommand};
|
||||
|
||||
pub const DESERIALIZE_INIT_COMPLETE_RAW_NAME: &str = "InCm";
|
||||
|
@ -19,7 +21,11 @@ impl DeserializedCommand for InitComplete {
|
|||
pub struct InitCompleteDeserializer {}
|
||||
|
||||
impl CommandDeserializer for InitCompleteDeserializer {
|
||||
fn deserialize(&self, _buffer: &[u8]) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||
fn deserialize(
|
||||
&self,
|
||||
_buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||
Arc::new(InitComplete {})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
|||
commands::command_base::{
|
||||
BasicWritableCommand, CommandDeserializer, DeserializedCommand, SerializableCommand,
|
||||
},
|
||||
enums::ProtocolVersion,
|
||||
state::util::get_mix_effect,
|
||||
};
|
||||
|
||||
|
@ -58,7 +59,11 @@ impl DeserializedCommand for ProgramInput {
|
|||
pub struct ProgramInputDeserializer {}
|
||||
|
||||
impl CommandDeserializer for ProgramInputDeserializer {
|
||||
fn deserialize(&self, buffer: &[u8]) -> Arc<dyn DeserializedCommand> {
|
||||
fn deserialize(
|
||||
&self,
|
||||
buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> Arc<dyn DeserializedCommand> {
|
||||
let mix_effect = buffer[0];
|
||||
let source = u16::from_be_bytes([buffer[2], buffer[3]]);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::{collections::VecDeque, sync::Arc};
|
||||
|
||||
use crate::enums::ProtocolVersion;
|
||||
|
||||
use super::{
|
||||
command_base::{CommandDeserializer, DeserializedCommand},
|
||||
device_profile::{
|
||||
|
@ -14,7 +16,10 @@ use super::{
|
|||
time::{TimeDeserializer, DESERIALIZE_TIME_RAW_NAME},
|
||||
};
|
||||
|
||||
pub fn deserialize_commands(payload: &[u8]) -> VecDeque<Arc<dyn DeserializedCommand>> {
|
||||
pub fn deserialize_commands(
|
||||
payload: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> VecDeque<Arc<dyn DeserializedCommand>> {
|
||||
let mut parsed_commands = VecDeque::new();
|
||||
let mut head = 0;
|
||||
|
||||
|
@ -31,13 +36,14 @@ pub fn deserialize_commands(payload: &[u8]) -> VecDeque<Arc<dyn DeserializedComm
|
|||
log::debug!("Received command {} with length {}", name, length);
|
||||
|
||||
if let Some(deserializer) = command_deserializer_from_string(name.as_str()) {
|
||||
let deserialized_command = deserializer.deserialize(&payload[head + 8..head + length]);
|
||||
let deserialized_command =
|
||||
deserializer.deserialize(&payload[head + 8..head + length], version);
|
||||
log::debug!("Received {:?}", deserialized_command);
|
||||
parsed_commands.push_back(deserialized_command);
|
||||
} else {
|
||||
log::warn!("Received command {name} for which there is no deserializer.");
|
||||
// TODO: Remove!
|
||||
todo!("Write deserializer for {name}.");
|
||||
// todo!("Write deserializer for {name}.");
|
||||
}
|
||||
|
||||
head += length;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::enums::ProtocolVersion;
|
||||
|
||||
use super::command_base::{CommandDeserializer, DeserializedCommand};
|
||||
|
||||
pub const DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME: &str = "TlSr";
|
||||
|
@ -29,7 +31,11 @@ impl DeserializedCommand for TallyBySource {
|
|||
pub struct TallyBySourceDeserializer {}
|
||||
|
||||
impl CommandDeserializer for TallyBySourceDeserializer {
|
||||
fn deserialize(&self, buffer: &[u8]) -> Arc<dyn DeserializedCommand> {
|
||||
fn deserialize(
|
||||
&self,
|
||||
buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> Arc<dyn DeserializedCommand> {
|
||||
let source_count = u16::from_be_bytes([buffer[0], buffer[1]]) as usize;
|
||||
|
||||
log::debug!("{:?}", buffer);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::enums::ProtocolVersion;
|
||||
|
||||
use super::command_base::{CommandDeserializer, DeserializedCommand};
|
||||
|
||||
pub const DESERIALIZE_TIME_RAW_NAME: &str = "Time";
|
||||
|
@ -33,6 +35,7 @@ impl CommandDeserializer for TimeDeserializer {
|
|||
fn deserialize(
|
||||
&self,
|
||||
buffer: &[u8],
|
||||
version: &ProtocolVersion,
|
||||
) -> std::sync::Arc<dyn super::command_base::DeserializedCommand> {
|
||||
let info = TimeInfo {
|
||||
hour: buffer[0],
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
pub enum Model {
|
||||
#[default]
|
||||
|
@ -71,7 +73,7 @@ impl From<u8> for Model {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
|
||||
pub enum ProtocolVersion {
|
||||
#[default]
|
||||
Unknown = 0,
|
||||
|
@ -98,6 +100,19 @@ impl TryFrom<u32> for ProtocolVersion {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for ProtocolVersion {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ProtocolVersion::Unknown => write!(f, "Unknown"),
|
||||
ProtocolVersion::V7_2 => write!(f, "v7.2"),
|
||||
ProtocolVersion::V7_5_2 => write!(f, "v7.5.2"),
|
||||
ProtocolVersion::V8_0 => write!(f, "v8.0"),
|
||||
ProtocolVersion::V8_0_1 => write!(f, "v8.0.1"),
|
||||
ProtocolVersion::V8_1_1 => write!(f, "v8.1.1"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum TransitionStyle {
|
||||
MIX = 0x00,
|
||||
|
|
Loading…
Reference in New Issue