use crate::std;
use std::fmt;
use crate::{
bool_enum, impl_message_ops, impl_omnibus_nop_reply, len::START_DOWNLOAD_REPLY, MessageOps,
MessageType,
};
pub mod index {
pub const DATA3: usize = 6;
}
bool_enum!(
DownloadReady,
"Indicates whether the device is ready to enter the firmware downloading phase."
);
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct StartDownloadReply {
buf: [u8; START_DOWNLOAD_REPLY],
}
impl StartDownloadReply {
pub fn new() -> Self {
let mut msg = Self {
buf: [0u8; START_DOWNLOAD_REPLY],
};
msg.init();
msg.set_message_type(MessageType::FirmwareDownload);
msg
}
pub fn download_ready(&self) -> DownloadReady {
((self.buf[index::DATA3] & 0b10) >> 1).into()
}
pub fn set_download_ready(&mut self, ready: DownloadReady) {
let b: u8 = ready.into();
self.buf[index::DATA3] = b << 1;
}
}
impl_message_ops!(StartDownloadReply);
impl_omnibus_nop_reply!(StartDownloadReply);
impl fmt::Display for StartDownloadReply {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"AckNak: {}, DeviceType: {}, MessageType: {}, DownloadReady: {}",
self.acknak(),
self.device_type(),
self.message_type(),
self.download_ready(),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Result;
#[test]
#[rustfmt::skip]
fn start_download_command_from_buf() -> Result<()> {
let msg_bytes = [
0x02, 0x0b, 0x50,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x03, 0x59,
];
let mut msg = StartDownloadReply::new();
msg.from_buf(msg_bytes.as_ref())?;
assert_eq!(msg.message_type(), MessageType::FirmwareDownload);
assert_eq!(msg.download_ready(), DownloadReady::Set);
let msg_bytes = [
0x02, 0x0b, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x5b,
];
msg.from_buf(msg_bytes.as_ref())?;
assert_eq!(msg.message_type(), MessageType::FirmwareDownload);
assert_eq!(msg.download_ready(), DownloadReady::Unset);
Ok(())
}
}