-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First stab at an HSL card reader core written in Rust
- Loading branch information
pingzing
committed
Jun 29, 2019
0 parents
commit 5de6cae
Showing
7 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/target | ||
**/*.rs.bk | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "scannit-core" | ||
version = "0.1.0" | ||
authors = ["Neil McAlister <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
chrono = "0.4" | ||
chrono-tz = "0.5" | ||
lazy_static = "1.3.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
mod desfire { | ||
// --- Commands --- | ||
///DESFire GetVersion command. | ||
const GET_VERSION_COMMAND: [u8; 5] = [144, 96, 00, 00, 00]; | ||
|
||
///DESFire command to return all installed application IDs on the card. | ||
const GET_APPLICATION_IDS_COMMAND: [u8; 5] = [144, 106, 00, 00, 00]; | ||
|
||
///DESFire Select Application command for selecting the HSL application on the card. | ||
///Returns OkResponse on success. | ||
const SELECT_HSL_COMMAND: [u8; 9] = [144, 90, 00, 00, 03, 20, 32, 239, 00]; | ||
|
||
///Command to read app info file, which contains application version, card name, etc. | ||
const READ_APP_INFO_COMMAND: [u8; 13] = [144, 189, 00, 00, 07, 08, 00, 00, 00, 11, 00, 00, 00]; | ||
|
||
///Command to read the season pass file on the card. | ||
const READ_PERIOD_PASS_COMMAND: [u8; 13] = | ||
[144, 189, 00, 00, 07, 01, 00, 00, 00, 32, 00, 00, 00]; | ||
|
||
///Command to read the stored value on the card. | ||
const READ_STORED_VALUE_COMMAND: [u8; 13] = | ||
[144, 189, 00, 00, 07, 02, 00, 00, 00, 12, 00, 00, 00]; | ||
|
||
///Command to read the active eTicket on the card. | ||
const READ_E_TICKET_COMMAND: [u8; 13] = [144, 189, 00, 00, 07, 03, 00, 00, 00, 26, 00, 00, 00]; | ||
|
||
///Command to read the 8 most recent transactions on the card. | ||
const READ_HISTORY_COMMAND: [u8; 13] = [144, 189, 00, 00, 07, 04, 00, 00, 00, 00, 00, 00, 00]; | ||
|
||
///Reads the remaining bytes-to-be-sent if a read request returned a MoreData response. | ||
const READ_NEXT_COMMAND: [u8; 5] = [144, 175, 00, 00, 00]; | ||
|
||
// --- Responses --- | ||
///DESFire OPERATION_OK response. In Hex: 0x91, 0x00. | ||
const OK_RESPONSE: [u8; 2] = [145, 00]; | ||
|
||
///DESFire error response. Not sure what it's known as internally. In Hex: 0x91, 0x9D. | ||
const ERROR_RESPONSE: [u8; 2] = [145, 157]; | ||
|
||
///DESFire ADDTIONAL_FRAME response. Indicates that more data is expected to be sent. In Hex: 0x91, 0xAF. | ||
const MORE_DATA_RESPONSE: [u8; 2] = [145, 175]; | ||
|
||
enum Command { | ||
GetVersion, | ||
GetApplicationIds, | ||
SelectHsl, | ||
ReadAppInfo, | ||
ReadPeriodPass, | ||
ReadStoredValue, | ||
ReadETicket, | ||
ReadHistory, | ||
ReadNext, | ||
} | ||
|
||
enum Response { | ||
Ok, | ||
Error, | ||
MoreData, | ||
} | ||
|
||
impl Command { | ||
fn value(&self) -> &[u8] { | ||
match *self { | ||
Command::GetVersion => &GET_VERSION_COMMAND, | ||
Command::GetApplicationIds => &GET_APPLICATION_IDS_COMMAND, | ||
Command::SelectHsl => &SELECT_HSL_COMMAND, | ||
Command::ReadAppInfo => &READ_APP_INFO_COMMAND, | ||
Command::ReadPeriodPass => &READ_PERIOD_PASS_COMMAND, | ||
Command::ReadStoredValue => &READ_STORED_VALUE_COMMAND, | ||
Command::ReadETicket => &READ_E_TICKET_COMMAND, | ||
Command::ReadHistory => &READ_HISTORY_COMMAND, | ||
Command::ReadNext => &READ_NEXT_COMMAND, | ||
} | ||
} | ||
} | ||
|
||
impl Response { | ||
fn value(&self) -> &[u8] { | ||
match *self { | ||
Response::Ok => &OK_RESPONSE, | ||
Response::Error => &ERROR_RESPONSE, | ||
Response::MoreData => &MORE_DATA_RESPONSE, | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
mod en1545date { | ||
use chrono::prelude::*; | ||
use chrono::Duration; | ||
use chrono_tz::Europe::Helsinki; | ||
use lazy_static::*; | ||
|
||
lazy_static! { | ||
static ref EN1545_ZERO_DATE: NaiveDateTime = NaiveDateTime::new( | ||
NaiveDate::from_ymd(1997, 01, 01), | ||
NaiveTime::from_hms(0, 0, 0) | ||
); | ||
} | ||
|
||
/// Convert from En1545 (number of days since 1997-01-01) to a standard UTC DateTime. | ||
/// # Arguments | ||
/// * `date` - The date in En1545 format (number of days since 1997-01-01). | ||
fn from_en1545_date(date: u16) -> DateTime<Utc> { | ||
from_en1545_date_and_time(date, 0u16) | ||
} | ||
|
||
/// Convert from En1545 (number of days since 1997-01-01, and number of minute since 00:00) to a standard UTC DateTime. | ||
/// # Arguments | ||
/// * `date` - The date in En1545 format (number of days since 1997-01-01). | ||
/// * `time` - The time in En1545 format (number minutes since 00:00). | ||
fn from_en1545_date_and_time(date: u16, time: u16) -> DateTime<Utc> { | ||
let local_datetime = | ||
*EN1545_ZERO_DATE + Duration::days(date as i64) + Duration::minutes(time as i64); | ||
// Assuming Helsinki because it's impossible to use an HSL travel card outside of Finland. | ||
// ...I hope. | ||
Helsinki | ||
.from_local_datetime(&local_datetime) | ||
.unwrap() | ||
.with_timezone(&Utc) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mod desfire; | ||
mod en1545date; | ||
mod travelcard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
fn it_works() { | ||
assert_eq!(2 + 2, 4); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
mod travelcard { | ||
pub struct TravelCard { | ||
// todo: lots of fields here once HSL publishes them | ||
} | ||
|
||
pub fn create_travel_card( | ||
app_info: &[u8], | ||
period_pass: &[u8], | ||
storedValue: &[u8], | ||
eTicket: &[u8], | ||
history: &[u8], | ||
) -> TravelCard { | ||
TravelCard {} | ||
} | ||
} |