Closed jedahan closed 1 year ago
Hello!
You should look into this section (link broken on mobile, open README at the bottom), which I think could answer this question.
TLDR: It is hardcoded, I provide an example that you copy directly into source code, didn’t bother doing it “correctly” as NFC refactor is coming. It’s something that’s worth doing when it comes out, but I don’t have a “proper” impl, which I assume should consume configuration from somewhere “up”.
I’ve heard about nfc-rpc, but didn’t try to use it. I thought it was doing isodep only. Have to look into it, perhaps it can send raw frames.
But IMO, i think adding this feature to flipper would make sense when they re-do the NFC stack. ECP can actually be implemented if a would-be nfc stack could allow to set custom NFC-A WUPA frames, which would mean that their code wouldn’t need to contain any proprietary terminology, and high-level apps can just invoke nfc polling with common WUPA and ECP passed in as parameters.
Wanted to add one last thing.
If/when you apply the example to the flipper's codebase, you'll find out that ECP frame there is just an placeholder. You can lookup the proper ECP frame in ecplist.json, but there's a need to calculate crc16a by hand (or find an appropriate parameter inside of ST hal).
Thank you for all the pointers, I'll stare, and let it stew in my head a bit while I learn more.
I saw the NFC refactor got merged and released like two weeks ago, so maybe waiting until post-1.0 is best.
Though the flipper devs are asking for specific feedback regarding the new NFC stack, I don't have the experience, maybe it is enough for me to ask them to "provide a mechanism to set custom NFC-A WUPA frames" if that isn't in the codebase already.
BTW I made those changes described and was able to flash the new firmware, but wasn't sure what client FAP I would also have to create to invoke that code, especially as a response to the AECP examples that use nfcpy.
Looks like lib/nfc/protocols/nfca.c has something called nfca_get_crc16 which seems promising
BTW I made those changes described and was able to flash the new firmware, but wasn't sure what client FAP I would also have to create to invoke that code, especially as a response to the AECP examples that use nfcpy.
I think that everything that uses ST's HAL works. For instance, the built-in "NFC" section almost fully. In the GIF i display it reading a card using "NFC/Extra Actions/Read Specific Card Type/DESFire" function.
Looks like lib/nfc/protocols/nfca.c has something called nfca_get_crc16 which seems promising
I'd advice not to complicate it for yourself until it starts working. Use online or some other calc for this value.
Full VAS ECP-A frame, for instance, is 6a01000002e4d2 (with crc), try it out at first. Iphone should at least get detected as generic "A" tag.
Cool - so when I do read DESFire, it triggers apple wallet, but then no read happens.
When I manually read NFC-A data, it does not trigger the wallet, but if I manually trigger to open wallet, it reads data. Seems to be unique each time which is probably a good sign.
btw, that function did work. I can share the patch/diff if you'd like, or not.
You can verify that it's working definitely by setting ecp to one of the car key frames (refer to json file), your phone should display a car pairing popup - in which case it's 100% working.
For DESFire, you have to choose between any of the available transit system ECP, It's up to you. VAS in this case is only for EMV payment.
And if it works with car key, then I think it's worth adding an example where crc doesn't need to be calculated manually.
Car key popped up immediately.
diff --git a/lib/ST25RFAL002/source/rfal_nfc.c b/lib/ST25RFAL002/source/rfal_nfc.c
index 57ff2e235..cea32c5c5 100644
--- a/lib/ST25RFAL002/source/rfal_nfc.c
+++ b/lib/ST25RFAL002/source/rfal_nfc.c
@@ -52,6 +52,7 @@
#include "rfal_nfc.h"
#include "utils.h"
#include "rfal_analogConfig.h"
+#include "../../nfc/protocols/nfca.h"
/*
******************************************************************************
@@ -993,6 +994,25 @@ static ReturnCode rfalNfcPollTechDetetection(void) {
gNfcDev.techsFound |= RFAL_NFC_POLL_TECH_A;
}
+ else {
+ uint8_t rx_data[0] = {};
+ uint16_t rx_len = 0;
+ #define FRAME_LEN 10
+ uint8_t frame[FRAME_LEN] = {0x6a, 0x02, 0xc3, 0x02, 0x09, 0x01, 0x00, 0x01, /*CRC1*/ 0x00, /*CRC2*/ 0x00};
+ nfca_append_crc16(frame, FRAME_LEN - 2);
+
+ rfalTransceiveBitsBlockingTxRx(
+ frame,
+ FRAME_LEN * 8,
+ rx_data,
+ 0,
+ &rx_len,
+ RFAL_TXRX_FLAGS_AGC_ON | RFAL_TXRX_FLAGS_CRC_TX_MANUAL,
+ 6780 // 13560U for 1 ms
+ );
+ #undef FRAME_LEN
+ }
+
gNfcDev.isTechInit = false;
gNfcDev.techs2do &= ~RFAL_NFC_POLL_TECH_A;
}
the #define stuff might have been dumb, but yeah basically just making sure the buffer has 2 bytes extra when initialized, and calling nfca_append_crc16
did the trick. There is also nfca_get_crc16
if you prefer less "magic".
LGTM, if you make a PR i'll accept it.
Thank you for all your work.
I was wondering, for getting these working on the flipper - did you implement a contactlessFrontend for nfcpy using the nfc-rpc, or did you hardcode the bytes in an entirely on-device manner?