summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nfcommander.h19
-rw-r--r--reader.c32
-rw-r--r--reader_yhy.c71
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);
diff --git a/reader.c b/reader.c
index 0ca56cf..5f1316b 100644
--- a/reader.c
+++ b/reader.c
@@ -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);