pub mod any;
pub mod component_mode_dpi;
pub mod control_word;
pub mod encrypted_dpi;
pub mod inject_section_data;
pub mod insert_alternate_break_duration;
pub mod insert_audio_descriptor;
pub mod insert_audio_provisioning;
pub mod insert_avail_descriptor;
pub mod insert_descriptor;
pub mod insert_dtmf_descriptor;
pub mod insert_segmentation_descriptor;
pub mod insert_tier;
pub mod insert_time_descriptor;
pub mod proprietary_command;
pub mod provisioning_request;
pub mod schedule_component_mode;
pub mod schedule_definition;
pub mod splice_null_request;
pub mod splice_request;
pub mod start_schedule_download;
pub mod time_signal_request;
pub mod transmit_schedule;
pub use any::AnyOperation;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Operation<'a> {
pub op_id: u16,
pub data: AnyOperation<'a>,
}
impl Operation<'_> {
#[must_use]
pub fn body_len(&self) -> usize {
self.data.body_len()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct GeneralResponse;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct InitRequest;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct InitResponse;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct AliveRequest {
pub time: crate::time::Time,
}
impl Default for AliveRequest {
fn default() -> Self {
Self {
time: crate::time::Time::zero(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct AliveResponse {
pub time: crate::time::Time,
}
impl Default for AliveResponse {
fn default() -> Self {
Self {
time: crate::time::Time::zero(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct InjectResponse {
pub message_number: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct InjectCompleteResponse {
pub message_number: u8,
pub cue_message_count: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct ConfigRequest {
pub as_ip_address: u32,
pub as_socket_number: u16,
pub activeflag: u8,
pub protocol_version: u8,
pub last_as_index: u8,
pub last_injectorcount: u16,
pub permanent_connection_requested: u8,
}
pub const CONFIG_REQUEST_LEN: usize = 12;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct ConfigResponse {
pub as_index: u8,
pub permanent_connection_requested: u8,
}
pub const CONFIG_RESPONSE_LEN: usize = 2;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct ProvisioningResponse;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct FaultRequest {
pub injector_ip_address: u32,
pub injector_socket_number: u16,
pub injector_service_name: [u8; 32],
pub dpi_pid_index: u16,
}
pub const FAULT_REQUEST_LEN: usize = 40;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct FaultResponse;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct AsAliveRequest;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct AsAliveResponse;
use crate::error::{Error, Result};
use crate::time::TIME_LEN;
use broadcast_common::{Parse, Serialize};
macro_rules! impl_empty_body {
($ty:ident, $what:literal, $oid:literal) => {
impl<'a> Parse<'a> for $ty {
type Error = Error;
fn parse(_bytes: &'a [u8]) -> Result<Self> {
Ok(Self)
}
}
impl Serialize for $ty {
type Error = Error;
fn serialized_len(&self) -> usize {
0
}
fn serialize_into(&self, _buf: &mut [u8]) -> Result<usize> {
Ok(0)
}
}
impl<'a> crate::traits::OperationDef<'a> for $ty {
const OP_ID: u16 = $oid;
const NAME: &'static str = $what;
}
};
}
impl_empty_body!(GeneralResponse, "GENERAL_RESPONSE", 0x0000);
impl_empty_body!(InitRequest, "INIT_REQUEST", 0x0001);
impl_empty_body!(InitResponse, "INIT_RESPONSE", 0x0002);
impl<'a> Parse<'a> for AliveRequest {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
Ok(Self {
time: crate::time::Time::parse(bytes)?,
})
}
}
impl Serialize for AliveRequest {
type Error = Error;
fn serialized_len(&self) -> usize {
TIME_LEN
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
self.time.serialize_into(buf)
}
}
impl crate::traits::OperationDef<'_> for AliveRequest {
const OP_ID: u16 = 0x0003;
const NAME: &'static str = "ALIVE_REQUEST";
}
impl<'a> Parse<'a> for AliveResponse {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
Ok(Self {
time: crate::time::Time::parse(bytes)?,
})
}
}
impl Serialize for AliveResponse {
type Error = Error;
fn serialized_len(&self) -> usize {
TIME_LEN
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
self.time.serialize_into(buf)
}
}
impl crate::traits::OperationDef<'_> for AliveResponse {
const OP_ID: u16 = 0x0004;
const NAME: &'static str = "ALIVE_RESPONSE";
}
impl<'a> Parse<'a> for InjectResponse {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
if bytes.is_empty() {
return Err(Error::BufferTooShort {
need: 1,
have: 0,
what: "inject_response message_number",
});
}
Ok(Self {
message_number: bytes[0],
})
}
}
impl Serialize for InjectResponse {
type Error = Error;
fn serialized_len(&self) -> usize {
1
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
if buf.is_empty() {
return Err(Error::OutputBufferTooSmall { need: 1, have: 0 });
}
buf[0] = self.message_number;
Ok(1)
}
}
impl crate::traits::OperationDef<'_> for InjectResponse {
const OP_ID: u16 = 0x0007;
const NAME: &'static str = "INJECT_RESPONSE";
}
impl<'a> Parse<'a> for InjectCompleteResponse {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
if bytes.len() < 2 {
return Err(Error::BufferTooShort {
need: 2,
have: bytes.len(),
what: "inject_complete_response",
});
}
Ok(Self {
message_number: bytes[0],
cue_message_count: bytes[1],
})
}
}
impl Serialize for InjectCompleteResponse {
type Error = Error;
fn serialized_len(&self) -> usize {
2
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
if buf.len() < 2 {
return Err(Error::OutputBufferTooSmall {
need: 2,
have: buf.len(),
});
}
buf[0] = self.message_number;
buf[1] = self.cue_message_count;
Ok(2)
}
}
impl crate::traits::OperationDef<'_> for InjectCompleteResponse {
const OP_ID: u16 = 0x0008;
const NAME: &'static str = "INJECT_COMPLETE_RESPONSE";
}
impl<'a> Parse<'a> for ConfigRequest {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
if bytes.len() < CONFIG_REQUEST_LEN {
return Err(Error::BufferTooShort {
need: CONFIG_REQUEST_LEN,
have: bytes.len(),
what: "config_request_data",
});
}
Ok(Self {
as_ip_address: u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
as_socket_number: u16::from_be_bytes([bytes[4], bytes[5]]),
activeflag: bytes[6],
protocol_version: bytes[7],
last_as_index: bytes[8],
last_injectorcount: u16::from_be_bytes([bytes[9], bytes[10]]),
permanent_connection_requested: bytes[11],
})
}
}
impl Serialize for ConfigRequest {
type Error = Error;
fn serialized_len(&self) -> usize {
CONFIG_REQUEST_LEN
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
if buf.len() < CONFIG_REQUEST_LEN {
return Err(Error::OutputBufferTooSmall {
need: CONFIG_REQUEST_LEN,
have: buf.len(),
});
}
buf[0..4].copy_from_slice(&self.as_ip_address.to_be_bytes());
buf[4..6].copy_from_slice(&self.as_socket_number.to_be_bytes());
buf[6] = self.activeflag;
buf[7] = self.protocol_version;
buf[8] = self.last_as_index;
buf[9..11].copy_from_slice(&self.last_injectorcount.to_be_bytes());
buf[11] = self.permanent_connection_requested;
Ok(CONFIG_REQUEST_LEN)
}
}
impl crate::traits::OperationDef<'_> for ConfigRequest {
const OP_ID: u16 = 0x0009;
const NAME: &'static str = "CONFIG_REQUEST";
}
impl<'a> Parse<'a> for ConfigResponse {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
if bytes.len() < CONFIG_RESPONSE_LEN {
return Err(Error::BufferTooShort {
need: CONFIG_RESPONSE_LEN,
have: bytes.len(),
what: "config_response_data",
});
}
Ok(Self {
as_index: bytes[0],
permanent_connection_requested: bytes[1],
})
}
}
impl Serialize for ConfigResponse {
type Error = Error;
fn serialized_len(&self) -> usize {
CONFIG_RESPONSE_LEN
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
if buf.len() < CONFIG_RESPONSE_LEN {
return Err(Error::OutputBufferTooSmall {
need: CONFIG_RESPONSE_LEN,
have: buf.len(),
});
}
buf[0] = self.as_index;
buf[1] = self.permanent_connection_requested;
Ok(CONFIG_RESPONSE_LEN)
}
}
impl crate::traits::OperationDef<'_> for ConfigResponse {
const OP_ID: u16 = 0x000A;
const NAME: &'static str = "CONFIG_RESPONSE";
}
impl_empty_body!(ProvisioningResponse, "PROVISIONING_RESPONSE", 0x000C);
impl<'a> Parse<'a> for FaultRequest {
type Error = Error;
fn parse(bytes: &'a [u8]) -> Result<Self> {
if bytes.len() < FAULT_REQUEST_LEN {
return Err(Error::BufferTooShort {
need: FAULT_REQUEST_LEN,
have: bytes.len(),
what: "fault_request_data",
});
}
let mut injector_service_name = [0u8; 32];
injector_service_name.copy_from_slice(&bytes[6..38]);
Ok(Self {
injector_ip_address: u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
injector_socket_number: u16::from_be_bytes([bytes[4], bytes[5]]),
injector_service_name,
dpi_pid_index: u16::from_be_bytes([bytes[38], bytes[39]]),
})
}
}
impl Serialize for FaultRequest {
type Error = Error;
fn serialized_len(&self) -> usize {
FAULT_REQUEST_LEN
}
fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
if buf.len() < FAULT_REQUEST_LEN {
return Err(Error::OutputBufferTooSmall {
need: FAULT_REQUEST_LEN,
have: buf.len(),
});
}
buf[0..4].copy_from_slice(&self.injector_ip_address.to_be_bytes());
buf[4..6].copy_from_slice(&self.injector_socket_number.to_be_bytes());
buf[6..38].copy_from_slice(&self.injector_service_name);
buf[38..40].copy_from_slice(&self.dpi_pid_index.to_be_bytes());
Ok(FAULT_REQUEST_LEN)
}
}
impl crate::traits::OperationDef<'_> for FaultRequest {
const OP_ID: u16 = 0x000F;
const NAME: &'static str = "FAULT_REQUEST";
}
impl_empty_body!(FaultResponse, "FAULT_RESPONSE", 0x0010);
impl_empty_body!(AsAliveRequest, "AS_ALIVE_REQUEST", 0x0011);
impl_empty_body!(AsAliveResponse, "AS_ALIVE_RESPONSE", 0x0012);
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum AnySingleOperation<'a> {
GeneralResponse(GeneralResponse),
InitRequest(InitRequest),
InitResponse(InitResponse),
AliveRequest(AliveRequest),
AliveResponse(AliveResponse),
InjectResponse(InjectResponse),
InjectCompleteResponse(InjectCompleteResponse),
ConfigRequest(ConfigRequest),
ConfigResponse(ConfigResponse),
ProvisioningRequest(crate::operations::provisioning_request::ProvisioningRequest),
ProvisioningResponse(ProvisioningResponse),
FaultRequest(FaultRequest),
FaultResponse(FaultResponse),
AsAliveRequest(AsAliveRequest),
AsAliveResponse(AsAliveResponse),
Unknown {
op_id: u16,
body: &'a [u8],
},
}
impl<'a> AnySingleOperation<'a> {
pub fn dispatch(op_id: u16, body: &'a [u8]) -> Result<Self> {
match op_id {
0x0000 => Ok(Self::GeneralResponse(GeneralResponse::parse(body)?)),
0x0001 => Ok(Self::InitRequest(InitRequest::parse(body)?)),
0x0002 => Ok(Self::InitResponse(InitResponse::parse(body)?)),
0x0003 => Ok(Self::AliveRequest(AliveRequest::parse(body)?)),
0x0004 => Ok(Self::AliveResponse(AliveResponse::parse(body)?)),
0x0007 => Ok(Self::InjectResponse(InjectResponse::parse(body)?)),
0x0008 => Ok(Self::InjectCompleteResponse(InjectCompleteResponse::parse(
body,
)?)),
0x0009 => Ok(Self::ConfigRequest(ConfigRequest::parse(body)?)),
0x000A => Ok(Self::ConfigResponse(ConfigResponse::parse(body)?)),
0x000B => Ok(Self::ProvisioningRequest(
crate::operations::provisioning_request::ProvisioningRequest::parse(body)?,
)),
0x000C => Ok(Self::ProvisioningResponse(ProvisioningResponse::parse(
body,
)?)),
0x000F => Ok(Self::FaultRequest(FaultRequest::parse(body)?)),
0x0010 => Ok(Self::FaultResponse(FaultResponse::parse(body)?)),
0x0011 => Ok(Self::AsAliveRequest(AsAliveRequest::parse(body)?)),
0x0012 => Ok(Self::AsAliveResponse(AsAliveResponse::parse(body)?)),
_ => Ok(Self::Unknown { op_id, body }),
}
}
#[must_use]
pub fn body_len(&self) -> usize {
match self {
Self::GeneralResponse(_) => 0,
Self::InitRequest(_) => 0,
Self::InitResponse(_) => 0,
Self::AliveRequest(a) => a.serialized_len(),
Self::AliveResponse(a) => a.serialized_len(),
Self::InjectResponse(r) => r.serialized_len(),
Self::InjectCompleteResponse(r) => r.serialized_len(),
Self::ConfigRequest(r) => r.serialized_len(),
Self::ConfigResponse(r) => r.serialized_len(),
Self::ProvisioningRequest(r) => r.serialized_len(),
Self::ProvisioningResponse(_) => 0,
Self::FaultRequest(r) => r.serialized_len(),
Self::FaultResponse(_) => 0,
Self::AsAliveRequest(_) => 0,
Self::AsAliveResponse(_) => 0,
Self::Unknown { body, .. } => body.len(),
}
}
pub fn serialize_body_into(&self, buf: &mut [u8]) -> Result<usize> {
match self {
Self::GeneralResponse(g) => g.serialize_into(buf),
Self::InitRequest(i) => i.serialize_into(buf),
Self::InitResponse(i) => i.serialize_into(buf),
Self::AliveRequest(a) => a.serialize_into(buf),
Self::AliveResponse(a) => a.serialize_into(buf),
Self::InjectResponse(r) => r.serialize_into(buf),
Self::InjectCompleteResponse(r) => r.serialize_into(buf),
Self::ConfigRequest(r) => r.serialize_into(buf),
Self::ConfigResponse(r) => r.serialize_into(buf),
Self::ProvisioningRequest(r) => r.serialize_into(buf),
Self::ProvisioningResponse(r) => r.serialize_into(buf),
Self::FaultRequest(r) => r.serialize_into(buf),
Self::FaultResponse(r) => r.serialize_into(buf),
Self::AsAliveRequest(r) => r.serialize_into(buf),
Self::AsAliveResponse(r) => r.serialize_into(buf),
Self::Unknown { body, .. } => {
if buf.len() < body.len() {
return Err(Error::OutputBufferTooSmall {
need: body.len(),
have: buf.len(),
});
}
buf[..body.len()].copy_from_slice(body);
Ok(body.len())
}
}
}
}