Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NFC MBTA CharlieCard parsing plugin #62

Merged
merged 5 commits into from
Mar 31, 2024
Merged

Conversation

zacharyweiss
Copy link
Contributor

What's new

Built NFC plugin for MBTA CharlieCard (Boston, MA, USA)

  • Implements read, verify, and parse
  • Lookups for all card types, and Blue & Orange Line fare gate IDs
  • Passes, some trip flags, and misc other fields yet to be reverse engineered

I'm not particularly adept with C, nor experienced in contributing to open-source projects, so feedback / review of the following sought, in decreasing order of importance:

  • Let me know if this is better suited as a PR to OFW, and allowed to percolate up to the CFWs. Initial PR made here simply as this is the FW I'm currently running (this plugin does not rely on any FW-specific features, to my knowledge); happy to see it included in any FWs, so long as credit & license is kept.
  • Check for memory leaks — I likely am not following best practices with memory management & cleanup, due to my ignorance of C.
  • Check that I am not being overly greedy with card validation & producing false-positives parses; the read and verify functions are largely taken as boilerplate from analogous plugins, as are the initial checks at the start of the parse function.
  • For those in Boston: help build out the mapping of fare gate IDs to stations! Take note of the IDs printed in the transaction log, and associate them to a station in the lengthy fare gate struct.

Credit & citations listed in header comment.


For the reviewer

  • I've uploaded the firmware with this patch to a device and verified its functionality
  • I've confirmed the bug to be fixed / feature to be stable

@Willy-JL
Copy link
Member

to respond in order:

  • absolutely, i suggest proposing a PR to OFW aswell! we welcome the changes here and usually they will get accepted faster into CFW's, but it would be great if it reached more users. can't speak as to whether they would accept it in OFW, but i'd say it's definitely worth a shot. also, it's an honor to hear you're using Momentum :D
  • from what i can see the code looks quite solid and clean, well done! only the one missing free() as i mentioned in the review, but other than that this is great as far as i'm concerned
  • i'm not that experienced with NFC plugins in that sense, i will get some smarter friends than me to have a look ;) but atleast, the read function looks solid, checking for error none rather than assuming a full read, handles partial reads correctly (this was a wide-spread issue a little while back)

thank you!

@Willy-JL Willy-JL added the feature New feature or request label Mar 31, 2024
@@ -833,6 +863,9 @@ static uint16_t type_parse(const MfClassicData* data) {
// bitshift (2bytes = 16 bits) by 6bits for just first 10bits
const uint16_t type1 = pos_to_num(data, 2, 1, 0, 2) >> 6;
const uint16_t type2 = pos_to_num(data, 3, 1, 0, 2) >> 6;
// might be wise to remove the assertion; then again, it's an effective way
// to crowdsource research, as hopefully if this isn't universally true,
// someone will come running when their app crashes — probably not a best practice though haha.
furi_assert(type1 == type2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

furi_assert() is compiled only when DEBUG=1 is enabled, which it is not by default, nor for production builds in Momentum, you'd need to compile with ./fbt <command> DEBUG=1, so assert should be fine here! if you want to enforce it in all builds, regardless of DEBUG flag, you can use furi_check()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know! For my own education: does that mean compiling without DEBUG strips that, and is independent of the debug setting on the flipper? Or is the check kept in the compiled fap regardless, and the DEBUG compile arg simply sets the debug mode flag (locally or globally) on the flipper after flashing/launching?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEBUG=1 refers to the compiler options, with DEBUG=0 (default) furi_assert() will be stripped completely. the Debug option in flipper settings allows to attacha live debugger, and to access some extra hidden functionality (raw reads, debug info in some parsers...), but will not bring back the stripped furi_assert() calls

Thanks Leptopt1los!
@Willy-JL
Copy link
Member

I asked @Leptopt1los from unleashed team about card verification, he said it looks great!

The only thing he advised is maybe not only checking key A but also the paired key B in parse(), just to be safe.

If you want to ge ahead with that, by all means do, otherwise we can merge as is :D

@zacharyweiss
Copy link
Contributor Author

Key B check added! Should be all set now. Time permitting, I'll also likely be slowly digging into the few remaining unknowns on the card over the coming weeks; is there a preferred PR / contributing etiquette here? (ie, only PR at "project end" to minimize the number of PRs to review? PR with each individual discovery / improvement to keep things bleeding-edge? other?)

Thanks again for y'all's input & help!

@Willy-JL
Copy link
Member

perfect, thank you! yes, feel free to make new PRs as you progress with the parser. as for timing, whatever works best for you, as long as its not like once per day xD

@Willy-JL Willy-JL merged commit 32eab97 into Next-Flip:dev Mar 31, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants