-
Notifications
You must be signed in to change notification settings - Fork 583
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
add protocol awareness to NFC card transceivers #2045
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for the proposal and the PR. We've been discussing this on Discord and I agree this is needed.
I'm fine all up with the implementation. It will make things much easier when we'll have to deal with even more protocols.
In the mean time, few comments.
src/devices/Card/NfcProtocol.cs
Outdated
|
||
/// <summary> | ||
/// Mifare Classic | ||
/// (proprietary commands on top of ISO/IEC 14443-3 Type A) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// (proprietary commands on top of ISO/IEC 14443-3 Type A) | |
/// Proprietary commands on top of ISO/IEC 14443-3 Type A |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure; I'll change this (and the same pattern in the other cases also).
src/devices/Card/NfcProtocol.cs
Outdated
Jewel = (1 << 3), | ||
|
||
/// <summary> | ||
/// JIS X 6319-4 (compatible with FeliCa) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// JIS X 6319-4 (compatible with FeliCa) | |
/// JIS X 6319-4. Compatible with FeliCa. |
src/devices/Card/NfcProtocol.cs
Outdated
JisX6319_4 = (1 << 4), | ||
|
||
/// <summary> | ||
/// JIS X 6319-4 (compatible with FeliCa) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// JIS X 6319-4 (compatible with FeliCa) | |
/// JIS X 6319-4. Compatible with FeliCa. |
src/devices/Card/NfcProtocol.cs
Outdated
/// <summary> | ||
/// JIS X 6319-4 (compatible with FeliCa) | ||
/// </summary> | ||
FeliCa = JisX6319_4, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why defining this one equal to the previous one? Isn't 1 enough for both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In retrospect, I don't have a strong reason, so I'll remove the duplicate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the improvement. This will indeed help a lot.
@Ellerbach @jdbruner after merge this mr, piplines failed. some one can resolve it. |
NFC is a complex ecosystem with multiple protocols at different layers of the stack. NFC chipsets support varying combinations of these, including special handling for some protocol-specific commands. As an example, ISO/IEC 14443 is one set of RF standards, for which 14443-3 defines initialization and anticollision (of two types, A and B), and 14443-4 defines a transmission protocol atop 14443-3. However, some protocols, notably Mifare Classic and Mifare Ultralight, use a proprietary command set atop 14443-3. Mifare Classic uses a proprietary authentication scheme, so NFC chipsets implement this authentication protocol. (Alas, security by obscurity was not successful at preventing Mifare Classic authentication from being broken, particularly because it uses a relatively short 64-bit key.)
Some Mifare Classic commands require multiple RF exchanges - these include Write16Bytes, and counter operations. The PN532 provides direct support for these commands, but this must be handled in software for other transceivers.
The PN532 also provides direct support for other protocols, such as chaining and retransmission for 14443-4.
In .NET IoT, all card transceivers derive from the
CardTransceiver
abstract base class and override a specific implementation of the abstractTransceive
method. This creates a common interface between the different NFC card types (MifareCard
,Ultralight
,CreditCard
) and the NFC transceiverHowever, the diversity of protocols and transceiver support creates challenges to implement this interface. The various implementations must deduce the type of data exchange that is being performed and handle the special cases (such as Mifare authentication and Mifare writes) appropriately. However, this is difficult to do in general, because there are multiple commands, and the commands used by different protocols overlap. For example, Mifare Classic's
AuthenticationA
command uses the same command byte as Ultralight'sGetVersion
command. For transceivers that support other protocols as well (such as Innovision Jewel or FeliCa) there is an even greater risk that commands will overlap.Therefore, this CR redefines the transceiver interface with a breaking change. A new enum,
Iot.Device.Card.NfcProtocol
defines protocols that may be understood specially by NFC transceivers. A new abstract propertySupportedProtocols
is added toCardTransceiver
and overridden by each transceiver to indicate the protocols it supports, including:The
Transceive
method has an additional parameter that specifies the protocol that the caller intends to use for this transaction:Each transceiver handles the protocols according to its specific implementation:
Mfrc522
uses this as an indication that it should handle a request as Mifare Classic (including authentiation and two-stage write operations) or 14443-3 (such as for Ultralight). [In theory the Mfrc522 could also be used for 14443-4, but its small FIFO is a significant obstacle.]Pn532
uses this to determine whether it should invoke its special handlers for various protocols (Mifare, Jewel, FeliCa, 14443-4) or simply pass through the request (14443-3, notably for Ultralight)Pn5180
uses this to recognize when it should perform special handling for Mifare ClassicMifareCard
always requests Mifare protocol.Ultralight
requests 14443-3 except for the "compatibility write" command, which has the same command code as Mifare Classic's write command, and requires a two-step operation.CreditCard
requests 14443-4.In addition, two additional abstract properties are defined in
CardTransceiver
:so that callers can determine whether their requests are appropriately sized.
This also includes some miscellaneous fixes:
Tested on a Raspberry Pi 4B with MFRC522, PN532, and PN5180 using Mifare Classic and Ultralight cards. This change didn't impact the code path in PN5180 for CreditCard, but I was not able to verify that there are no regressions here.
Microsoft Reviewers: Open in CodeFlow