diff options
author | cbdev <cb@cbcdn.com> | 2023-06-22 01:11:31 +0200 |
---|---|---|
committer | cbdev <cb@cbcdn.com> | 2023-06-22 01:11:31 +0200 |
commit | e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0 (patch) | |
tree | f16ca27ce915768b700de0d5be29f1206b7499ba | |
parent | cb686cd6314d3e181bd91c0f2d449750c9429be7 (diff) | |
download | nfcommander-e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0.tar.gz nfcommander-e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0.tar.bz2 nfcommander-e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0.zip |
Basic NTAG support
-rw-r--r-- | nfcommander.h | 10 | ||||
-rw-r--r-- | reader.c | 32 | ||||
-rw-r--r-- | reader_yhy.c | 52 |
3 files changed, 79 insertions, 15 deletions
diff --git a/nfcommander.h b/nfcommander.h index 79b8790..b4622a1 100644 --- a/nfcommander.h +++ b/nfcommander.h @@ -7,12 +7,11 @@ #endif typedef enum { - tag_unset, + tag_unset, /*unknown tag type*/ + tag_unknown, /*unsupported tag*/ tag_mifare1, tag_ntag, - tag_desfire, - tag_ultralight, - tag_ultralightc + tag_desfire } nfc_tag_t; #define FLAG_TAG_DATA_VALID 1 @@ -25,6 +24,9 @@ typedef struct { nfc_tag_t type; uint8_t uid_length; uint8_t uid[10]; + //storage + size_t bytes_available; + size_t granularity; } nfc_tag_info_t; typedef int (*reader_plugin_init)(void); @@ -86,6 +86,24 @@ int reader_init(){ return reader_init_backend(); } +static void reader_print_tag(nfc_tag_info_t tag){ + size_t n = 0; + char* type = "UNST"; + switch(tag.type){ + case tag_unset: type = "UNST"; break; + case tag_unknown: type = "UNKN"; break; + case tag_mifare1: type = "MFR1"; break; + case tag_ntag: type = "NTAG"; break; + case tag_desfire: type = "DESF"; break; + } + + printf("[%s", type); + for(n = 0; n < tag.uid_length; n++){ + printf(" %02X", tag.uid[n]); + } + printf("]"); +} + static void reader_expire(){ size_t n = 0; for(n = 0; n < MAX_TAGS; n++){ @@ -101,16 +119,22 @@ static int reader_process(){ //new tag tags[n].flags |= FLAG_ACTIVE; if(tags[n].flags & FLAG_TAG_LOCKED){ - printf("A tag was detected (slot %lu), but no key is known\n", n); + printf("Slot %2lu: ", n); + reader_print_tag(tags[n].info); + printf(" locked, unusable\n"); return 0; } if(tags[n].flags & FLAG_TAG_UNPROGRAMMED){ - printf("Unprogrammed tag detected (slot %lu)\n", n); + printf("Slot %2lu: ", n); + reader_print_tag(tags[n].info); + printf(" unprogrammed\n"); //TODO return 0; } if(tags[n].flags & FLAG_TAG_DATA_VALID){ - printf("Command tag detected (slot %lu)\n", n); + printf("Slot %2lu: ", n); + reader_print_tag(tags[n].info); + printf(" valid\n"); //TODO return 0; } @@ -136,7 +160,7 @@ int reader_tag_present(uint8_t flags, nfc_tag_info_t tag){ size_t n = 0; //sanitize input flags - flags &= (FLAG_TAG_DATA_VALID | FLAG_TAG_UNPROGRAMMED | FLAG_TAG_LOCKED); + flags &= (TAG_STATUS_FLAGS); //check if tag already known for(n = 0; n < MAX_TAGS; n++){ diff --git a/reader_yhy.c b/reader_yhy.c index 7e0d8c3..41f20d8 100644 --- a/reader_yhy.c +++ b/reader_yhy.c @@ -48,18 +48,56 @@ int scan(){ uint16_t atqa = 0; uint8_t sak = 0; + uint8_t data[16]; + uint8_t bytes; for(yhy_sync_request(reader_fd, 1, &atqa); atqa; yhy_sync_request(reader_fd, 0, &atqa)){ - card.uid_length = yhy_sync_anticoll(reader_fd, card.uid, sizeof(card.uid)); - if(!card.uid_length){ - return 0; + sak = 0; + //ATQA should normally not be used as an indicator for UID length + //However, the YHY UL_SELECT command does not seem to work after CL1 anticollision for some reason + + //extended length UIDs + if(atqa & 0x00C0){ + card.uid_length = yhy_sync_ulselect(reader_fd, card.uid, sizeof(card.uid)); + //since we dont get either the CL2 SAK or any other method of identifying the particular type of PICC, just guess whether it's an NTAG + card.type = tag_unknown; + if(atqa == 0x0044){ + card.type = tag_ntag; + card.bytes_available = 140; + card.granularity = 4; + } + else{ + printf("PICC Parameters: ATQA %04X\n", atqa); + } + } + else{ + card.uid_length = yhy_sync_anticoll(reader_fd, card.uid, sizeof(card.uid)); + yhy_sync_select(reader_fd, card.uid, card.uid_length, &sak); + + card.type = tag_unknown; + if(atqa == 0x0004 && sak == 0x08){ + card.type = tag_mifare1; + card.bytes_available = 752; + card.granularity = 16; + } + else{ + printf("PICC Parameters: ATQA %04X SAK %02X\n", atqa, sak); + } } - - yhy_sync_select(reader_fd, card.uid, card.uid_length, &sak); - //TODO parse ATQA and SAK to detect tag type if(reader_tag_present(0, card) == TAG_READ_REQUESTED){ - //TODO read card data + //read card data + if(card.type == tag_ntag){ + //capability container in page 3, byte 2 + // + // //0x12 -> ntag213 + // //0x3e -> ntag215 + // //0x6d -> ntag216 + //user data in pages 4 trough 39 + bytes = yhy_sync_read(reader_fd, 3, data, sizeof(data)); + } + else if(card.type == tag_mifare1){ + } reader_tag_present(FLAG_TAG_LOCKED, card); } |