feat: _pin command
This commit is contained in:
parent
c5ed966070
commit
493bf7a6e8
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
atem_lib::atem_socket::{AtemEvent, AtemSocketCommand, AtemSocketMessage, TrackingId},
|
atem_lib::atem_socket::{AtemEvent, AtemSocketCommand, AtemSocketMessage, TrackingId},
|
||||||
commands::{
|
commands::{
|
||||||
command_base::{BasicWritableCommand, DeserializedCommand},
|
command_base::{BasicWritableCommand, DeserializedCommand},
|
||||||
device_profile::DESERIALIZE_VERSION_RAW_NAME,
|
device_profile::version::DESERIALIZE_VERSION_RAW_NAME,
|
||||||
init_complete::DESERIALIZE_INIT_COMPLETE_RAW_NAME,
|
init_complete::DESERIALIZE_INIT_COMPLETE_RAW_NAME,
|
||||||
time::DESERIALIZE_TIME_RAW_NAME,
|
time::DESERIALIZE_TIME_RAW_NAME,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,34 +1,2 @@
|
||||||
use std::sync::Arc;
|
pub mod product_identifier;
|
||||||
|
pub mod version;
|
||||||
use crate::enums::ProtocolVersion;
|
|
||||||
|
|
||||||
use super::command_base::{CommandDeserializer, DeserializedCommand};
|
|
||||||
|
|
||||||
pub const DESERIALIZE_VERSION_RAW_NAME: &str = "_ver";
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct VersionCommand {
|
|
||||||
pub version: ProtocolVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeserializedCommand for VersionCommand {
|
|
||||||
fn raw_name(&self) -> &'static str {
|
|
||||||
DESERIALIZE_VERSION_RAW_NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
|
||||||
state.info.api_version = self.version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct VersionCommandDeserializer {}
|
|
||||||
|
|
||||||
impl CommandDeserializer for VersionCommandDeserializer {
|
|
||||||
fn deserialize(&self, buffer: &[u8]) -> 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");
|
|
||||||
|
|
||||||
Arc::new(VersionCommand { version })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
use std::{ffi::CString, sync::Arc};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
commands::command_base::{CommandDeserializer, DeserializedCommand},
|
||||||
|
enums::Model,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DESERIALIZE_PRODUCT_IDENTIFIER_RAW_NAME: &str = "_pin";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProductIdentifierCommand {
|
||||||
|
pub product_identifier: String,
|
||||||
|
pub model: Model,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeserializedCommand for ProductIdentifierCommand {
|
||||||
|
fn raw_name(&self) -> &'static str {
|
||||||
|
DESERIALIZE_PRODUCT_IDENTIFIER_RAW_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||||
|
state.info.product_identifier = Some(self.product_identifier.clone());
|
||||||
|
state.info.model = self.model.clone();
|
||||||
|
|
||||||
|
match state.info.model {
|
||||||
|
Model::TwoME
|
||||||
|
| Model::TwoME4K
|
||||||
|
| Model::TwoMEBS4K
|
||||||
|
| Model::Constellation
|
||||||
|
| Model::Constellation8K
|
||||||
|
| Model::ConstellationHD4ME
|
||||||
|
| Model::Constellation4K4ME => {
|
||||||
|
state.info.power = vec![false, false];
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
state.info.power = vec![false];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ProductIdentifierCommandDeserializer {}
|
||||||
|
|
||||||
|
impl CommandDeserializer for ProductIdentifierCommandDeserializer {
|
||||||
|
fn deserialize(&self, buffer: &[u8]) -> std::sync::Arc<dyn DeserializedCommand> {
|
||||||
|
let null_byte_index = buffer
|
||||||
|
.iter()
|
||||||
|
.position(|byte| *byte == b'\0')
|
||||||
|
.expect("No null byte");
|
||||||
|
let product_identifier =
|
||||||
|
CString::from_vec_with_nul(buffer[..(null_byte_index + 1)].to_vec())
|
||||||
|
.expect("Malformed string");
|
||||||
|
let model = buffer[40];
|
||||||
|
|
||||||
|
Arc::new(ProductIdentifierCommand {
|
||||||
|
product_identifier: product_identifier
|
||||||
|
.to_str()
|
||||||
|
.expect("Invalid rust string")
|
||||||
|
.to_string(),
|
||||||
|
model: model.into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
commands::command_base::{CommandDeserializer, DeserializedCommand},
|
||||||
|
enums::ProtocolVersion,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DESERIALIZE_VERSION_RAW_NAME: &str = "_ver";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct VersionCommand {
|
||||||
|
pub version: ProtocolVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeserializedCommand for VersionCommand {
|
||||||
|
fn raw_name(&self) -> &'static str {
|
||||||
|
DESERIALIZE_VERSION_RAW_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||||
|
state.info.api_version = self.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct VersionCommandDeserializer {}
|
||||||
|
|
||||||
|
impl CommandDeserializer for VersionCommandDeserializer {
|
||||||
|
fn deserialize(&self, buffer: &[u8]) -> 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");
|
||||||
|
|
||||||
|
Arc::new(VersionCommand { version })
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,12 @@ use std::{collections::VecDeque, sync::Arc};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
command_base::{CommandDeserializer, DeserializedCommand},
|
command_base::{CommandDeserializer, DeserializedCommand},
|
||||||
device_profile::{VersionCommandDeserializer, DESERIALIZE_VERSION_RAW_NAME},
|
device_profile::{
|
||||||
|
product_identifier::{
|
||||||
|
ProductIdentifierCommandDeserializer, DESERIALIZE_PRODUCT_IDENTIFIER_RAW_NAME,
|
||||||
|
},
|
||||||
|
version::{VersionCommandDeserializer, DESERIALIZE_VERSION_RAW_NAME},
|
||||||
|
},
|
||||||
init_complete::{InitCompleteDeserializer, DESERIALIZE_INIT_COMPLETE_RAW_NAME},
|
init_complete::{InitCompleteDeserializer, DESERIALIZE_INIT_COMPLETE_RAW_NAME},
|
||||||
mix_effects::program_input::{ProgramInputDeserializer, DESERIALIZE_PROGRAM_INPUT_RAW_NAME},
|
mix_effects::program_input::{ProgramInputDeserializer, DESERIALIZE_PROGRAM_INPUT_RAW_NAME},
|
||||||
tally_by_source::{TallyBySourceDeserializer, DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME},
|
tally_by_source::{TallyBySourceDeserializer, DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME},
|
||||||
|
@ -29,6 +34,10 @@ pub fn deserialize_commands(payload: &[u8]) -> VecDeque<Arc<dyn DeserializedComm
|
||||||
let deserialized_command = deserializer.deserialize(&payload[head + 8..head + length]);
|
let deserialized_command = deserializer.deserialize(&payload[head + 8..head + length]);
|
||||||
log::debug!("Received {:?}", deserialized_command);
|
log::debug!("Received {:?}", deserialized_command);
|
||||||
parsed_commands.push_back(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}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
head += length;
|
head += length;
|
||||||
|
@ -44,6 +53,9 @@ fn command_deserializer_from_string(command_str: &str) -> Option<Box<dyn Command
|
||||||
DESERIALIZE_PROGRAM_INPUT_RAW_NAME => Some(Box::<ProgramInputDeserializer>::default()),
|
DESERIALIZE_PROGRAM_INPUT_RAW_NAME => Some(Box::<ProgramInputDeserializer>::default()),
|
||||||
DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME => Some(Box::<TallyBySourceDeserializer>::default()),
|
DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME => Some(Box::<TallyBySourceDeserializer>::default()),
|
||||||
DESERIALIZE_TIME_RAW_NAME => Some(Box::<TimeDeserializer>::default()),
|
DESERIALIZE_TIME_RAW_NAME => Some(Box::<TimeDeserializer>::default()),
|
||||||
|
DESERIALIZE_PRODUCT_IDENTIFIER_RAW_NAME => {
|
||||||
|
Some(Box::<ProductIdentifierCommandDeserializer>::default())
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#[derive(Clone, Default, PartialEq)]
|
#[derive(Debug, Clone, Default, PartialEq)]
|
||||||
pub enum Model {
|
pub enum Model {
|
||||||
#[default]
|
#[default]
|
||||||
Unknown = 0x00,
|
Unknown = 0x00,
|
||||||
|
@ -19,6 +19,56 @@ pub enum Model {
|
||||||
MiniProISO = 0x0f,
|
MiniProISO = 0x0f,
|
||||||
MiniExtreme = 0x10,
|
MiniExtreme = 0x10,
|
||||||
MiniExtremeISO = 0x11,
|
MiniExtremeISO = 0x11,
|
||||||
|
ConstellationHD1ME = 0x12,
|
||||||
|
ConstellationHD2ME = 0x13,
|
||||||
|
ConstellationHD4ME = 0x14,
|
||||||
|
SDI = 0x15,
|
||||||
|
SDIProISO = 0x16,
|
||||||
|
SDIExtremeISO = 0x17,
|
||||||
|
// 0x18 ??
|
||||||
|
// 0x19 ??
|
||||||
|
TelevisionStudioHD8 = 0x1a,
|
||||||
|
TelevisionStudioHD8ISO = 0x1b,
|
||||||
|
// 0x1c ??
|
||||||
|
// 0x1d ??
|
||||||
|
Constellation4K4ME = 0x1e,
|
||||||
|
// 0x1f ??
|
||||||
|
TelevisionStudio4K8 = 0x20,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for Model {
|
||||||
|
fn from(value: u8) -> Self {
|
||||||
|
match value {
|
||||||
|
0x01 => Model::TVS,
|
||||||
|
0x02 => Model::OneME,
|
||||||
|
0x03 => Model::TwoME,
|
||||||
|
0x04 => Model::PS4K,
|
||||||
|
0x05 => Model::OneME4K,
|
||||||
|
0x06 => Model::TwoME4K,
|
||||||
|
0x07 => Model::TwoMEBS4K,
|
||||||
|
0x08 => Model::TVSHD,
|
||||||
|
0x09 => Model::TVSProHD,
|
||||||
|
0x0a => Model::TVSPro4K,
|
||||||
|
0x0b => Model::Constellation,
|
||||||
|
0x0c => Model::Constellation8K,
|
||||||
|
0x0d => Model::Mini,
|
||||||
|
0x0e => Model::MiniPro,
|
||||||
|
0x0f => Model::MiniProISO,
|
||||||
|
0x10 => Model::MiniExtreme,
|
||||||
|
0x11 => Model::MiniExtremeISO,
|
||||||
|
0x12 => Model::ConstellationHD1ME,
|
||||||
|
0x13 => Model::ConstellationHD2ME,
|
||||||
|
0x14 => Model::ConstellationHD4ME,
|
||||||
|
0x15 => Model::SDI,
|
||||||
|
0x16 => Model::SDIProISO,
|
||||||
|
0x17 => Model::SDIExtremeISO,
|
||||||
|
0x1a => Model::TelevisionStudioHD8,
|
||||||
|
0x1b => Model::TelevisionStudioHD8ISO,
|
||||||
|
0x1e => Model::Constellation4K4ME,
|
||||||
|
0x20 => Model::TelevisionStudio4K8,
|
||||||
|
_ => Model::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||||
|
|
Loading…
Reference in New Issue