ledger_lib/
info.rs

1//! Device information types and connection filters
2
3use strum::{Display, EnumString};
4
5use super::transport;
6
7/// Ledger device information
8#[derive(Clone, PartialEq, Debug)]
9pub struct LedgerInfo {
10    /// Device Model
11    pub model: Model,
12
13    /// Device connection information
14    pub conn: ConnInfo,
15}
16
17impl std::fmt::Display for LedgerInfo {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        write!(f, "{} ({})", self.model, self.conn)
20    }
21}
22
23/// Ledger device models
24#[derive(Clone, PartialEq, Debug, Display, EnumString)]
25pub enum Model {
26    /// Nano S
27    NanoS,
28    /// Nano S Plus
29    NanoSPlus,
30    /// Nano X
31    NanoX,
32    /// Stax
33    Stax,
34    /// Unknown model
35    Unknown(u16),
36}
37
38impl Model {
39    /// Convert a USB PID to a [Model] kind
40    ///
41    /// Note that ledger PIDs vary depending on the device state so only the top byte is used
42    /// for matching.
43    pub fn from_pid(pid: u16) -> Model {
44        match pid & 0xFF00 {
45            // TODO: support all the models
46            //0x0001 => Ok(Model::NanoS),
47            0x4000 => Model::NanoX,
48            0x5000 => Model::NanoSPlus,
49            //0x0006 => Ok(Model::Stax),
50            _ => Model::Unknown(pid),
51        }
52    }
53}
54
55/// Ledger connection information
56#[derive(Clone, PartialEq, Debug)]
57pub enum ConnInfo {
58    #[cfg(feature = "transport_usb")]
59    Usb(transport::UsbInfo),
60    #[cfg(feature = "transport_tcp")]
61    Tcp(transport::TcpInfo),
62    #[cfg(feature = "transport_ble")]
63    Ble(transport::BleInfo),
64}
65
66impl std::fmt::Display for ConnInfo {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        match self {
69            #[cfg(feature = "transport_usb")]
70            Self::Usb(i) => write!(f, "HID {}", i),
71            #[cfg(feature = "transport_tcp")]
72            Self::Tcp(i) => write!(f, "TCP {}", i),
73            #[cfg(feature = "transport_ble")]
74            Self::Ble(i) => write!(f, "BLE {}", i),
75        }
76    }
77}
78
79#[cfg(feature = "transport_usb")]
80impl From<transport::UsbInfo> for ConnInfo {
81    fn from(value: transport::UsbInfo) -> Self {
82        Self::Usb(value)
83    }
84}
85
86#[cfg(feature = "transport_tcp")]
87impl From<transport::TcpInfo> for ConnInfo {
88    fn from(value: transport::TcpInfo) -> Self {
89        Self::Tcp(value)
90    }
91}
92
93#[cfg(feature = "transport_ble")]
94impl From<transport::BleInfo> for ConnInfo {
95    fn from(value: transport::BleInfo) -> Self {
96        Self::Ble(value)
97    }
98}
99
100/// Application info object
101#[derive(Debug, Clone, PartialEq)]
102pub struct AppInfo {
103    pub name: String,
104    pub version: String,
105    pub flags: ledger_proto::apdus::AppFlags,
106}
107
108/// Device info object
109#[derive(Debug, Clone, PartialEq)]
110pub struct DeviceInfo {
111    pub target_id: [u8; 4],
112    pub se_version: String,
113    pub mcu_version: String,
114    pub flags: Vec<u8>,
115}