use crate::std;
use std::fmt;
use crate::{
impl_message_ops, impl_omnibus_nop_reply, len::QUERY_DEVICE_CAPABILITIES_REPLY, MessageOps,
MessageType,
};
pub mod index {
pub const CAP0: usize = 3;
pub const CAP1: usize = 4;
pub const CAP2: usize = 5;
pub const CAP3: usize = 6;
pub const CAP4: usize = 7;
pub const CAP5: usize = 8;
}
bitfield! {
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Cap0(u8);
u8;
pub extended_pup_mode, _: 0;
pub extended_orientation, _: 1;
pub application_and_variant_id, _: 2;
pub bnf_status, _: 3;
pub test_documents, _: 4;
pub bezel, _: 5;
pub easitrax, _: 6;
}
impl fmt::Display for Cap0 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{")?;
write!(f, r#""extended_pup_mode":{},"#, self.extended_pup_mode())?;
write!(
f,
r#""extended_orientation":{},"#,
self.extended_orientation()
)?;
write!(
f,
r#""application_and_variant_id":{},"#,
self.application_and_variant_id()
)?;
write!(f, r#""bnf_status":{},"#, self.bnf_status())?;
write!(f, r#""test_documents":{},"#, self.test_documents())?;
write!(f, r#""bezel":{},"#, self.bezel())?;
write!(f, r#""easitrax":{}"#, self.easitrax())?;
write!(f, "}}")
}
}
impl From<u8> for Cap0 {
fn from(b: u8) -> Self {
Self(b & 0b111_1111)
}
}
impl From<&Cap0> for u8 {
fn from(c: &Cap0) -> Self {
c.0
}
}
impl From<Cap0> for u8 {
fn from(c: Cap0) -> Self {
(&c).into()
}
}
bitfield! {
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Cap1(u8);
u8;
pub note_retrieved, _: 0;
pub advanced_bookmark, _: 1;
pub abds_download, _: 2;
pub clear_audit, _: 3;
pub multi_note_escrow, _: 4;
pub unix_timestamp_32bit, _: 5;
}
impl fmt::Display for Cap1 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{")?;
write!(f, r#""note_retrieved":{},"#, self.note_retrieved())?;
write!(f, r#""advanced_bookmark":{},"#, self.advanced_bookmark())?;
write!(f, r#""abds_download\":{},"#, self.abds_download())?;
write!(f, r#""clear_audit\":{},"#, self.clear_audit())?;
write!(f, r#"multi_note_escrow\":{},"#, self.multi_note_escrow())?;
write!(
f,
r#""unix_timestamp_32bit":{}"#,
self.unix_timestamp_32bit()
)?;
write!(f, "}}")
}
}
impl From<u8> for Cap1 {
fn from(b: u8) -> Self {
Self(b & 0b11_1111)
}
}
impl From<&Cap1> for u8 {
fn from(c: &Cap1) -> Self {
c.0
}
}
impl From<Cap1> for u8 {
fn from(c: Cap1) -> Self {
(&c).into()
}
}
bitfield! {
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Cap2(u8);
u8;
pub one_denom_recycling, _: 0;
pub two_denom_recycling, _: 1;
pub three_denom_recycling, _: 2;
pub four_denom_recycling, _: 3;
pub improperly_seated_head_detection, _: 4;
pub mixed_denom_recycling, _: 6;
}
impl fmt::Display for Cap2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{")?;
write!(
f,
r#""one_denom_recycling":{},"#,
self.one_denom_recycling()
)?;
write!(
f,
r#""two_denom_recycling":{},"#,
self.two_denom_recycling()
)?;
write!(
f,
r#""three_denom_recycling\":{},"#,
self.three_denom_recycling()
)?;
write!(
f,
r#""four_denom_recycling\":{},"#,
self.four_denom_recycling()
)?;
write!(
f,
r#""improperly_seated_head_detection":{},"#,
self.improperly_seated_head_detection()
)?;
write!(
f,
r#""mixed_denom_recycling":{}"#,
self.mixed_denom_recycling()
)?;
write!(f, "}}")
}
}
impl From<u8> for Cap2 {
fn from(b: u8) -> Self {
Self(b & 0b101_1111)
}
}
impl From<&Cap2> for u8 {
fn from(c: &Cap2) -> Self {
c.0
}
}
impl From<Cap2> for u8 {
fn from(c: Cap2) -> Self {
(&c).into()
}
}
bitfield! {
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Cap3(u8);
u8;
pub customer_config, _: 0;
pub banknote_classification, _: 1;
}
impl fmt::Display for Cap3 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
r#"{{"customer_config":{},"banknote_classification":{}}}"#,
self.customer_config(),
self.banknote_classification(),
)
}
}
impl From<u8> for Cap3 {
fn from(b: u8) -> Self {
Self(b & 0x000_0011)
}
}
impl From<&Cap3> for u8 {
fn from(c: &Cap3) -> Self {
c.0
}
}
impl From<Cap3> for u8 {
fn from(c: Cap3) -> Self {
(&c).into()
}
}
bitfield! {
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Cap4(u8);
u8;
pub reserved, _: 6, 0;
}
impl fmt::Display for Cap4 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, r#"{{"reserved": 0b{:08b}}}"#, self.reserved())
}
}
impl From<u8> for Cap4 {
fn from(b: u8) -> Self {
Self(b & 0b111_1111)
}
}
impl From<&Cap4> for u8 {
fn from(c: &Cap4) -> Self {
c.0
}
}
impl From<Cap4> for u8 {
fn from(c: Cap4) -> Self {
(&c).into()
}
}
bitfield! {
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Cap5(u8);
u8;
pub reserved, _: 6, 0;
}
impl fmt::Display for Cap5 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, r#"{{"reserved": 0b{:08b}}}"#, self.reserved())
}
}
impl From<u8> for Cap5 {
fn from(b: u8) -> Self {
Self(b & 0b111_1111)
}
}
impl From<&Cap5> for u8 {
fn from(c: &Cap5) -> Self {
c.0
}
}
impl From<Cap5> for u8 {
fn from(c: Cap5) -> Self {
(&c).into()
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct QueryDeviceCapabilitiesReply {
buf: [u8; QUERY_DEVICE_CAPABILITIES_REPLY],
}
impl QueryDeviceCapabilitiesReply {
pub fn new() -> Self {
let mut message = Self {
buf: [0u8; QUERY_DEVICE_CAPABILITIES_REPLY],
};
message.init();
message.set_message_type(MessageType::AuxCommand);
message
}
pub fn cap0(&self) -> Cap0 {
self.buf[index::CAP0].into()
}
pub fn cap1(&self) -> Cap1 {
self.buf[index::CAP1].into()
}
pub fn cap2(&self) -> Cap2 {
self.buf[index::CAP2].into()
}
pub fn cap3(&self) -> Cap3 {
self.buf[index::CAP3].into()
}
pub fn cap4(&self) -> Cap4 {
self.buf[index::CAP4].into()
}
pub fn cap5(&self) -> Cap5 {
self.buf[index::CAP5].into()
}
}
impl_message_ops!(QueryDeviceCapabilitiesReply);
impl_omnibus_nop_reply!(QueryDeviceCapabilitiesReply);
impl fmt::Display for QueryDeviceCapabilitiesReply {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"AckNak: {}, DeviceType: {}, MessageType: {}, Capability set 0: {}, Capability set 1: {}, Capability set 2: {}, Capability set 3: {}, Capability set 4: {}, Capability set 5: {}",
self.acknak(),
self.device_type(),
self.message_type(),
self.cap0(),
self.cap1(),
self.cap2(),
self.cap3(),
self.cap4(),
self.cap5(),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Result;
#[test]
#[rustfmt::skip]
fn test_query_device_capabilities_reply_from_buf() -> Result<()> {
let msg_bytes = [
0x02, 0x0b, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x6b,
];
let mut msg = QueryDeviceCapabilitiesReply::new();
msg.from_buf(msg_bytes.as_ref())?;
assert_eq!(msg.message_type(), MessageType::AuxCommand);
assert_eq!(msg.cap0(), Cap0::from(0));
assert_eq!(msg.cap1(), Cap1::from(0));
assert_eq!(msg.cap2(), Cap2::from(0));
assert_eq!(msg.cap3(), Cap3::from(0));
assert_eq!(msg.cap4(), Cap4::from(0));
assert_eq!(msg.cap5(), Cap5::from(0));
Ok(())
}
}