186 lines
6.6 KiB
Rust
186 lines
6.6 KiB
Rust
use crate::data_types::DataType;
|
|
use crate::identifier::Identifier;
|
|
use crate::packet::packet_data::PacketData;
|
|
use crate::packet::raw_packet::RawPacket;
|
|
use crate::packet::{Packet, ToPacket};
|
|
use crate::prelude::as_u32_be;
|
|
use std::io;
|
|
|
|
pub mod vec;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum PropertyControlCommand {
|
|
Register {
|
|
property_name: String,
|
|
data_type: u8,
|
|
read_only: bool,
|
|
// TODO: descriptive
|
|
},
|
|
Remove {
|
|
property_name: String,
|
|
},
|
|
Get {
|
|
property_name: String,
|
|
data: DataType,
|
|
},
|
|
Set {
|
|
property_name: String,
|
|
data: DataType,
|
|
},
|
|
Reset {
|
|
property_name: String,
|
|
},
|
|
Subscribe {
|
|
device_id: Identifier,
|
|
property_name: String,
|
|
},
|
|
Unsubscribe {
|
|
device_id: Identifier,
|
|
property_name: String,
|
|
},
|
|
}
|
|
|
|
impl PropertyControlCommand {
|
|
pub fn command(&self) -> u8 {
|
|
match self {
|
|
PropertyControlCommand::Register { .. } => 0x10,
|
|
PropertyControlCommand::Remove { .. } => 0x11,
|
|
PropertyControlCommand::Get { .. } => 0x12,
|
|
PropertyControlCommand::Set { .. } => 0x13,
|
|
PropertyControlCommand::Reset { .. } => 0x14,
|
|
PropertyControlCommand::Subscribe { .. } => 0x1A,
|
|
PropertyControlCommand::Unsubscribe { .. } => 0x1B,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ToPacket for PropertyControlCommand {
|
|
fn to_packet(
|
|
self,
|
|
src: Identifier,
|
|
dest: Identifier,
|
|
packet_id: Identifier,
|
|
reply_to: Identifier,
|
|
) -> Packet {
|
|
Packet {
|
|
src,
|
|
dest,
|
|
packet_id,
|
|
reply_to,
|
|
command: self.command(),
|
|
data: PacketData::PropertyControl(self.clone()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<RawPacket> for PropertyControlCommand {
|
|
type Error = io::Error;
|
|
fn try_from(raw_packet: RawPacket) -> io::Result<Self> {
|
|
let build_invalid_input_err = |r: &str| Err(io::Error::new(io::ErrorKind::InvalidInput, r));
|
|
match raw_packet.command {
|
|
// remove node
|
|
0x10 => {
|
|
if raw_packet.data_length == 34 {
|
|
Ok(PropertyControlCommand::Register {
|
|
property_name: String::from_utf8(raw_packet.data[..32].to_vec()).map_err(
|
|
|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"),
|
|
)?,
|
|
data_type: raw_packet.data[33],
|
|
read_only: raw_packet.data[34] != 0,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 34 bytes")
|
|
}
|
|
}
|
|
// remove property
|
|
0x11 => {
|
|
if raw_packet.data_length == 32 {
|
|
Ok(PropertyControlCommand::Remove {
|
|
property_name: String::from_utf8(raw_packet.data.to_vec()).map_err(
|
|
|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"),
|
|
)?,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 32 bytes")
|
|
}
|
|
}
|
|
// get property
|
|
0x12 => {
|
|
if raw_packet.data_length == 33 {
|
|
Ok(PropertyControlCommand::Get {
|
|
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
|
|
.map_err(|_| {
|
|
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
|
|
})?,
|
|
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 33 bytes")
|
|
}
|
|
}
|
|
// set property
|
|
0x13 => {
|
|
if raw_packet.data_length == 33 {
|
|
Ok(PropertyControlCommand::Set {
|
|
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
|
|
.map_err(|_| {
|
|
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
|
|
})?,
|
|
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 33 bytes")
|
|
}
|
|
}
|
|
// reset property
|
|
0x14 => {
|
|
if raw_packet.data_length == 33 {
|
|
Ok(PropertyControlCommand::Reset {
|
|
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
|
|
.map_err(|_| {
|
|
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
|
|
})?,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 33 bytes")
|
|
}
|
|
}
|
|
// subscribe to property
|
|
0x1A => {
|
|
if raw_packet.data_length == 36 {
|
|
Ok(PropertyControlCommand::Subscribe {
|
|
device_id: Identifier::from(as_u32_be(
|
|
raw_packet.data[0x14..0x18].as_ref(),
|
|
)),
|
|
property_name: String::from_utf8(raw_packet.data[0x18..0x4C].to_vec())
|
|
.map_err(|_| {
|
|
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
|
|
})?,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 36 bytes")
|
|
}
|
|
}
|
|
// unsubscribe from property
|
|
0x1B => {
|
|
if raw_packet.data_length == 36 {
|
|
Ok(PropertyControlCommand::Unsubscribe {
|
|
device_id: Identifier::from(as_u32_be(
|
|
raw_packet.data[0x14..0x18].as_ref(),
|
|
)),
|
|
property_name: String::from_utf8(raw_packet.data[0x18..0x4C].to_vec())
|
|
.map_err(|_| {
|
|
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
|
|
})?,
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 36 bytes")
|
|
}
|
|
}
|
|
_ => Err(io::Error::new(
|
|
io::ErrorKind::InvalidInput,
|
|
"command group is unsupported",
|
|
)),
|
|
}
|
|
}
|
|
}
|