diff options
-rw-r--r-- | nfcommander.h | 19 | ||||
-rw-r--r-- | reader.c | 32 | ||||
-rw-r--r-- | reader_yhy.c | 71 |
3 files changed, 95 insertions, 27 deletions
diff --git a/nfcommander.h b/nfcommander.h index b4622a1..00f0fb8 100644 --- a/nfcommander.h +++ b/nfcommander.h @@ -17,6 +17,7 @@ typedef enum { #define FLAG_TAG_DATA_VALID 1 #define FLAG_TAG_UNPROGRAMMED 2 #define FLAG_TAG_LOCKED 4 +#define FLAG_TAG_READONLY 8 #define TAG_STATUS_FLAGS ((FLAG_TAG_DATA_VALID | FLAG_TAG_UNPROGRAMMED | FLAG_TAG_LOCKED)) typedef struct { @@ -24,9 +25,14 @@ typedef struct { nfc_tag_t type; uint8_t uid_length; uint8_t uid[10]; - //storage + //storage info size_t bytes_available; size_t granularity; + //data + size_t static_length; + uint8_t* static_data; + size_t dynamic_length; + uint8_t* dynamic_data; } nfc_tag_info_t; typedef int (*reader_plugin_init)(void); @@ -45,8 +51,13 @@ int core_manage_fd(int fd, int manage, notification_target_t system); * This API is to be called by reader backends to indicate presence of a tag. * This can be done as soon as the UID of the tag has been read (ie. before * reading EEPROM contents) to check whether the card has already been read. - * If this API returns 1, a full read is requested and the nfc_tag_info_t should - * be submitted again with the data fully read. + * + * If this API returns TAG_READ_REQUESTED, a full read is requested and the + * nfc_tag_info_t should be submitted again with the data fully read. + * + * If this API returns TAG_WRITE_REQUESTED, the nfc_tag_into_t has been filled + * with valid data pointers and sizes to be writen to the tag */ #define TAG_READ_REQUESTED 1 -int reader_tag_present(uint8_t flags, nfc_tag_info_t tag); +#define TAG_WRITE_REQUESTED 2 +int reader_tag_present(uint8_t flags, nfc_tag_info_t* tag); @@ -13,8 +13,8 @@ #define DEFAULT_POLL_TIMEOUT 1000 #define MAX_TAGS 5 -#define FLAG_PRESENT 8 -#define FLAG_ACTIVE 16 +#define FLAG_PRESENT 16 +#define FLAG_ACTIVE 32 static void* reader_module = NULL; static reader_plugin_handle reader_backend_handle = NULL; @@ -92,12 +92,12 @@ static void reader_print_tag(nfc_tag_info_t tag){ switch(tag.type){ case tag_unset: type = "UNST"; break; case tag_unknown: type = "UNKN"; break; - case tag_mifare1: type = "MFR1"; break; + case tag_mifare1: type = "MIFR"; break; case tag_ntag: type = "NTAG"; break; case tag_desfire: type = "DESF"; break; } - printf("[%s", type); + printf("[%s:%lu", type, tag.bytes_available); for(n = 0; n < tag.uid_length; n++){ printf(" %02X", tag.uid[n]); } @@ -111,6 +111,16 @@ static void reader_expire(){ } } +static void tag_info_free(nfc_tag_info_t* tag){ + free(tag->static_data); + tag->static_data = NULL; + tag->static_length = 0; + + free(tag->dynamic_data); + tag->dynamic_data = NULL; + tag->dynamic_length = 0; +} + static int reader_process(){ size_t n = 0; for(n = 0; n < MAX_TAGS; n++){ @@ -144,8 +154,8 @@ static int reader_process(){ } else{ if(tags[n].flags & FLAG_ACTIVE){ - //tag was removed - //TODO + //tag was removed - free any allocated members + tag_info_free(&(tags[n].info)); printf("Tag in slot %lu removed\n", n); } @@ -156,7 +166,7 @@ static int reader_process(){ return 0; } -int reader_tag_present(uint8_t flags, nfc_tag_info_t tag){ +int reader_tag_present(uint8_t flags, nfc_tag_info_t* tag){ size_t n = 0; //sanitize input flags @@ -165,15 +175,15 @@ int reader_tag_present(uint8_t flags, nfc_tag_info_t tag){ //check if tag already known for(n = 0; n < MAX_TAGS; n++){ if((tags[n].flags & (FLAG_PRESENT | FLAG_ACTIVE)) - && tags[n].info.uid_length == tag.uid_length - && !memcmp(tags[n].info.uid, tag.uid, tag.uid_length)){ + && tags[n].info.uid_length == tag->uid_length + && !memcmp(tags[n].info.uid, tag->uid, tag->uid_length)){ //mark still present tags[n].flags |= FLAG_PRESENT; //if full data submitted, copy in and set flags if(!(tags[n].flags & TAG_STATUS_FLAGS)){ if(flags & TAG_STATUS_FLAGS){ - memcpy(&(tags[n].info), &tag, sizeof(tag)); + memcpy(&(tags[n].info), tag, sizeof(nfc_tag_info_t)); tags[n].flags |= flags; return 0; } @@ -188,7 +198,7 @@ int reader_tag_present(uint8_t flags, nfc_tag_info_t tag){ for(n = 0; n < MAX_TAGS; n++){ if(!tags[n].flags){ tags[n].flags |= FLAG_PRESENT | flags; - memcpy(&(tags[n].info), &tag, sizeof(tag)); + memcpy(&(tags[n].info), tag, sizeof(nfc_tag_info_t)); return (tags[n].flags & TAG_STATUS_FLAGS) ? 0 : TAG_READ_REQUESTED; } } diff --git a/reader_yhy.c b/reader_yhy.c index 41f20d8..92d5080 100644 --- a/reader_yhy.c +++ b/reader_yhy.c @@ -41,6 +41,60 @@ int handle(int fd){ return 0; } +uint8_t read_ntag(nfc_tag_info_t* tag){ + uint8_t data[16]; + size_t bytes; + + //read 16 bytes starting at block 2 + //[0-3] UID, lock bytes + //[4-7] CC + //[8-11] Signature + //[12-15] Data block offsets & lengths + bytes = yhy_sync_read(reader_fd, 2, data, sizeof(data)); + if(bytes != 16){ + //read failed, probably not a usable tag + return FLAG_TAG_LOCKED; + } + + //check for NTAG signature CC bytes + if(data[4] != 0xE1 || data[5] != 0x10 || data[7]){ + return FLAG_TAG_LOCKED; + } + + switch(data[6]){ + case 0x12: + //NTAG213 + tag->bytes_available = 144; + break; + case 0x3E: + //NTAG215 + tag->bytes_available = 496; + break; + case 0x6D: + //NTAG216 + tag->bytes_available = 872; + break; + default: + //unknown + return FLAG_TAG_LOCKED; + } + + //TODO check lock bits + + //check nfcommander signature + if(data[8] != 0xCB || data[9] != 'N' || data[10] != 'F' || data[11] != 'C'){ + return FLAG_TAG_UNPROGRAMMED; + } + + + return 0; +} + +uint8_t read_mifare(nfc_tag_info_t* tag){ + //TODO + return 0; +} + int scan(){ nfc_tag_info_t card = { 0 @@ -48,8 +102,7 @@ int scan(){ uint16_t atqa = 0; uint8_t sak = 0; - uint8_t data[16]; - uint8_t bytes; + uint8_t flags; for(yhy_sync_request(reader_fd, 1, &atqa); atqa; yhy_sync_request(reader_fd, 0, &atqa)){ sak = 0; @@ -63,7 +116,6 @@ int scan(){ card.type = tag_unknown; if(atqa == 0x0044){ card.type = tag_ntag; - card.bytes_available = 140; card.granularity = 4; } else{ @@ -85,20 +137,15 @@ int scan(){ } } - if(reader_tag_present(0, card) == TAG_READ_REQUESTED){ + if(reader_tag_present(0, &card) == TAG_READ_REQUESTED){ //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)); + flags = read_ntag(&card); } else if(card.type == tag_mifare1){ + flags = read_mifare(&card); } - reader_tag_present(FLAG_TAG_LOCKED, card); + reader_tag_present(flags, &card); } yhy_sync_hlta(reader_fd); |