scannit_core/
desfire.rs

1// --- Commands ---
2///DESFire GetVersion command.
3pub const GET_VERSION_COMMAND: [u8; 5] = [0x90, 0x60, 0x00, 0x00, 0x00];
4
5///DESFire command to return all installed application IDs on the card.
6pub const GET_APPLICATION_IDS_COMMAND: [u8; 5] = [0x90, 0x6A, 0x00, 0x00, 0x00];
7
8///DESFire Select Application command for selecting the HSL application on the card.
9///Returns OkResponse on success.
10pub const SELECT_HSL_COMMAND: [u8; 9] = [0x90, 0x5A, 0x00, 0x00, 0x03, 0x14, 0x20, 0xEF, 0x00];
11
12///Command to read app info file, which contains application version, card name, etc.
13pub const READ_APP_INFO_COMMAND: [u8; 13] = [
14    0x90, 0xBD, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
15];
16
17///Command to read the control info file from the card.
18pub const READ_CONTROL_INFO_COMMAND: [u8; 13] = [
19    0x90, 0xBD, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
20];
21
22///Command to read the season pass file on the card.
23pub const READ_PERIOD_PASS_COMMAND: [u8; 13] = [
24    0x90, 0xBD, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
25];
26
27///Command to read the stored value on the card.
28pub const READ_STORED_VALUE_COMMAND: [u8; 13] = [
29    0x90, 0xBD, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
30];
31
32///Command to read the active eTicket on the card.
33pub const READ_E_TICKET_COMMAND: [u8; 13] = [
34    0x90, 0xBD, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
35];
36
37///Command to read the 8 most recent transactions on the card.
38pub const READ_HISTORY_COMMAND: [u8; 13] = [
39    0x90, 0xBB, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40];
41
42///Reads the remaining bytes-to-be-sent if a read request returned a MoreData response.
43pub const READ_NEXT_COMMAND: [u8; 5] = [0x90, 0xAF, 0x00, 0x00, 0x00];
44
45// --- Responses ---
46///DESFire OPERATION_OK response.
47pub const OK_RESPONSE: [u8; 2] = [0x91, 0x00];
48
49///DESFire error response. Not sure what it's known as internally.
50pub const ERROR_RESPONSE: [u8; 2] = [0x91, 0x9D];
51
52///DESFire ADDTIONAL_FRAME response. Indicates that there is more data, if the caller would like to ask for it.
53pub const MORE_DATA_RESPONSE: [u8; 2] = [0x91, 0xAF];
54
55/// A DESFire APDU command that the HSL card accepts.
56pub enum Command {
57    ///DESFire GetVersion command.
58    GetVersion,
59
60    ///DESFire command to return all installed application IDs on the card.
61    GetApplicationIds,
62
63    ///DESFire Select Application command for selecting the HSL application on the card.
64    ///Returns OkResponse on success.
65    SelectHsl,
66
67    ///Command to read app info file, which contains application version, card name, etc.
68    ReadAppInfo,
69
70    ///Command to read the control info file from the card.
71    ReadControlInfo,
72
73    ///Command to read the season pass file on the card.
74    ReadPeriodPass,
75
76    ///Command to read the stored value on the card.
77    ReadStoredValue,
78
79    ///Command to read the active eTicket on the card.
80    ReadETicket,
81
82    ///Command to read the 8 most recent transactions on the card.
83    ReadHistory,
84
85    ///Reads the remaining bytes-to-be-sent if a read request returned a MoreData response.
86    ReadNext,
87}
88
89/// Possible DESFire responses to APDU command from the HSL card.
90#[derive(Copy, Clone)]
91pub enum Response {
92    ///DESFire OPERATION_OK response.
93    Ok,
94
95    ///DESFire error response. Not sure what it's known as internally.
96    Error,
97
98    ///DESFire ADDTIONAL_FRAME response. Indicates that there is more data, if the caller would like to ask for it.
99    MoreData,
100}
101
102impl Into<&[u8]> for Command {
103    fn into(self) -> &'static [u8] {
104        match self {
105            Command::GetVersion => &GET_VERSION_COMMAND,
106            Command::GetApplicationIds => &GET_APPLICATION_IDS_COMMAND,
107            Command::SelectHsl => &SELECT_HSL_COMMAND,
108            Command::ReadAppInfo => &READ_APP_INFO_COMMAND,
109            Command::ReadControlInfo => &READ_CONTROL_INFO_COMMAND,
110            Command::ReadPeriodPass => &READ_PERIOD_PASS_COMMAND,
111            Command::ReadStoredValue => &READ_STORED_VALUE_COMMAND,
112            Command::ReadETicket => &READ_E_TICKET_COMMAND,
113            Command::ReadHistory => &READ_HISTORY_COMMAND,
114            Command::ReadNext => &READ_NEXT_COMMAND,
115        }
116    }
117}
118
119impl Into<&[u8]> for Response {
120    fn into(self) -> &'static [u8] {
121        match self {
122            Response::Ok => &OK_RESPONSE,
123            Response::Error => &ERROR_RESPONSE,
124            Response::MoreData => &MORE_DATA_RESPONSE,
125        }
126    }
127}
128
129impl std::cmp::PartialEq<Response> for [u8] {
130    fn eq(&self, other: &Response) -> bool {
131        self == Into::<&[u8]>::into(*other)
132    }
133}
134
135impl std::cmp::PartialEq<Response> for &[u8] {
136    fn eq(&self, other: &Response) -> bool {
137        *self == Into::<&[u8]>::into(*other)
138    }
139}