summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2023-06-22 01:11:31 +0200
committercbdev <cb@cbcdn.com>2023-06-22 01:11:31 +0200
commite27446a8f8c470cc7a41cfeec1e6ffe4f23478e0 (patch)
treef16ca27ce915768b700de0d5be29f1206b7499ba
parentcb686cd6314d3e181bd91c0f2d449750c9429be7 (diff)
downloadnfcommander-e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0.tar.gz
nfcommander-e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0.tar.bz2
nfcommander-e27446a8f8c470cc7a41cfeec1e6ffe4f23478e0.zip
Basic NTAG support
-rw-r--r--nfcommander.h10
-rw-r--r--reader.c32
-rw-r--r--reader_yhy.c52
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);
diff --git a/reader.c b/reader.c
index f37ade4..0ca56cf 100644
--- a/reader.c
+++ b/reader.c
@@ -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);
}