summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2006-12-01 13:29:00 +0000
committerlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2006-12-01 13:29:00 +0000
commitf0a3a3f8c4f39dfacf2d370bd23b27cd5b3358bf (patch)
tree9980bd638b3df4f71088adc3f191dd4cbc392de5
parent8b39e78b9d52a6c87ef0a4ab8402d7188f94e788 (diff)
- add size detection for mifare classic / ultralight
- add possibility to obtain ATQA via getopt - fix default -EINVAL return of tcl getopt git-svn-id: https://svn.gnumonks.org/trunk/librfid@1930 e0336214-984f-0b4b-a45f-81c69e1f0ede
-rw-r--r--include/librfid/rfid_layer2_iso14443a.h2
-rw-r--r--include/librfid/rfid_protocol.h1
-rw-r--r--include/librfid/rfid_protocol_mifare_classic.h4
-rw-r--r--src/rfid_layer2_iso14443a.c35
-rw-r--r--src/rfid_proto_mifare_classic.c30
-rw-r--r--src/rfid_proto_mifare_ul.c28
-rw-r--r--src/rfid_proto_tcl.c2
-rw-r--r--src/rfid_protocol.c1
-rw-r--r--utils/librfid-tool.c7
9 files changed, 101 insertions, 9 deletions
diff --git a/include/librfid/rfid_layer2_iso14443a.h b/include/librfid/rfid_layer2_iso14443a.h
index 283e6b6..b9ef954 100644
--- a/include/librfid/rfid_layer2_iso14443a.h
+++ b/include/librfid/rfid_layer2_iso14443a.h
@@ -4,6 +4,7 @@
enum rfid_14443a_opt {
RFID_OPT_14443A_SPEED_RX = 0x00010001,
RFID_OPT_14443A_SPEED_TX = 0x00010002,
+ RFID_OPT_14443A_ATQA = 0x00010003,
};
enum rfid_14443_opt_speed {
@@ -56,6 +57,7 @@ struct iso14443a_handle {
unsigned int state;
unsigned int level;
unsigned int tcl_capable;
+ struct iso14443a_atqa atqa;
};
enum iso14443a_level {
diff --git a/include/librfid/rfid_protocol.h b/include/librfid/rfid_protocol.h
index fd649ef..06f704f 100644
--- a/include/librfid/rfid_protocol.h
+++ b/include/librfid/rfid_protocol.h
@@ -45,6 +45,7 @@ enum rfid_protocol_id {
enum rfid_protocol_opt {
RFID_OPT_PROTO_ID,
+ RFID_OPT_PROTO_SIZE = 0x10000001,
};
#ifdef __LIBRFID__
diff --git a/include/librfid/rfid_protocol_mifare_classic.h b/include/librfid/rfid_protocol_mifare_classic.h
index 99c447d..b20a028 100644
--- a/include/librfid/rfid_protocol_mifare_classic.h
+++ b/include/librfid/rfid_protocol_mifare_classic.h
@@ -17,6 +17,10 @@
#define RFID_CMD_MIFARE_AUTH1A 0x60
#define RFID_CMD_MIFARE_AUTH1B 0x61
+enum rfid_proto_mfcl_opt {
+ RFID_OPT_P_MFCL_SIZE = 0x10000001,
+};
+
#ifdef __LIBRFID__
extern const struct rfid_protocol rfid_protocol_mfcl;
diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c
index 2ee7eb0..429577c 100644
--- a/src/rfid_layer2_iso14443a.c
+++ b/src/rfid_layer2_iso14443a.c
@@ -100,22 +100,22 @@ iso14443a_anticol(struct rfid_layer2_handle *handle)
int ret;
unsigned int uid_size;
struct iso14443a_handle *h = &handle->priv.iso14443a;
- struct iso14443a_atqa atqa;
+ struct iso14443a_atqa *atqa = &h->atqa;
struct iso14443a_anticol_cmd acf;
unsigned int bit_of_col;
unsigned char sak[3];
unsigned int rx_len = sizeof(sak);
- char *aqptr = (char *) &atqa;
+ char *aqptr = (char *) atqa;
memset(handle->uid, 0, sizeof(handle->uid));
memset(sak, 0, sizeof(sak));
- memset(&atqa, 0, sizeof(atqa));
+ memset(atqa, 0, sizeof(&atqa));
memset(&acf, 0, sizeof(acf));
if (handle->flags & RFID_OPT_LAYER2_WUP)
- ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_WUPA, &atqa);
+ ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_WUPA, atqa);
else
- ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_REQA, &atqa);
+ ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_REQA, atqa);
if (ret < 0) {
h->state = ISO14443A_STATE_REQA_SENT;
DEBUGP("error during transceive_sf: %d\n", ret);
@@ -125,15 +125,15 @@ iso14443a_anticol(struct rfid_layer2_handle *handle)
DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1));
- if (!atqa.bf_anticol) {
+ if (!atqa->bf_anticol) {
h->state = ISO14443A_STATE_NO_BITFRAME_ANTICOL;
DEBUGP("no bitframe anticollission bits set, aborting\n");
return -1;
}
- if (atqa.uid_size == 2 || atqa.uid_size == 3)
+ if (atqa->uid_size == 2 || atqa->uid_size == 3)
uid_size = 3;
- else if (atqa.uid_size == 1)
+ else if (atqa->uid_size == 1)
uid_size = 2;
else
uid_size = 1;
@@ -285,6 +285,24 @@ iso14443a_setopt(struct rfid_layer2_handle *handle, int optname,
return ret;
}
+static int
+iso14443a_getopt(struct rfid_layer2_handle *handle, int optname,
+ void *optval, unsigned int optlen)
+{
+ int ret = -EINVAL;
+ struct iso14443a_handle *h = &handle->priv.iso14443a;
+ struct iso14443a_atqa *atqa = optval;
+
+ switch (optname) {
+ case RFID_OPT_14443A_ATQA:
+ *atqa = h->atqa;
+ ret = 0;
+ break;
+ };
+
+ return ret;
+}
+
static struct rfid_layer2_handle *
iso14443a_init(struct rfid_reader_handle *rh)
@@ -328,6 +346,7 @@ const struct rfid_layer2 rfid_layer2_iso14443a = {
.close = &iso14443a_hlta,
.fini = &iso14443a_fini,
.setopt = &iso14443a_setopt,
+ .getopt = &iso14443a_getopt,
},
};
diff --git a/src/rfid_proto_mifare_classic.c b/src/rfid_proto_mifare_classic.c
index 4032b80..c2020b0 100644
--- a/src/rfid_proto_mifare_classic.c
+++ b/src/rfid_proto_mifare_classic.c
@@ -140,6 +140,35 @@ mfcl_write(struct rfid_protocol_handle *ph, unsigned int page,
return ret;
}
+static int
+mfcl_getopt(struct rfid_protocol_handle *ph, int optname, void *optval,
+ unsigned int *optlen)
+{
+ int ret = -EINVAL;
+ u_int16_t atqa;
+ unsigned int atqa_size = sizeof(atqa);
+ unsigned int *size = optval;
+
+ switch (optname) {
+ case RFID_OPT_PROTO_SIZE:
+ if (*optlen < sizeof(*size))
+ return -EINVAL;
+ *optlen = sizeof(*size);
+ ret = 0;
+ rfid_layer2_getopt(ph->l2h, RFID_OPT_14443A_ATQA,
+ (void *) &atqa, &atqa_size);
+ if (atqa == 0x0004)
+ *size = 1024;
+ else if (atqa == 0x0002)
+ *size = 4096;
+ else
+ ret = -EIO;
+ break;
+ }
+
+ return ret;
+}
+
static struct rfid_protocol_handle *
mfcl_init(struct rfid_layer2_handle *l2h)
{
@@ -169,6 +198,7 @@ const struct rfid_protocol rfid_protocol_mfcl = {
.read = &mfcl_read,
.write = &mfcl_write,
.fini = &mfcl_fini,
+ .getopt = &mfcl_getopt,
},
};
diff --git a/src/rfid_proto_mifare_ul.c b/src/rfid_proto_mifare_ul.c
index 8981b5e..65347b1 100644
--- a/src/rfid_proto_mifare_ul.c
+++ b/src/rfid_proto_mifare_ul.c
@@ -108,14 +108,41 @@ mful_transceive(struct rfid_protocol_handle *ph,
return -EINVAL;
}
+static int
+mful_getopt(struct rfid_protocol_handle *ph, int optname, void *optval,
+ unsigned int optlen)
+{
+ int ret = -EINVAL;
+ u_int16_t atqa;
+ unsigned int *size = optval;
+
+ switch (optname) {
+ case RFID_OPT_PROTO_SIZE:
+ ret = 0;
+ *size = 512;
+ break;
+ }
+
+ return ret;
+}
+
+
static struct rfid_protocol_handle *
mful_init(struct rfid_layer2_handle *l2h)
{
struct rfid_protocol_handle *ph;
+ u_int16_t atqa;
+ unsigned int atqa_len = sizeof(atqa);
if (l2h->l2->id != RFID_LAYER2_ISO14443A)
return NULL;
+ /* According to "Type Identification Procedure Rev. 1.3" */
+ rfid_layer2_getopt(l2h, RFID_OPT_14443A_ATQA,
+ &atqa, atqa_len);
+ if (atqa != 0x0044)
+ return NULL;
+
/* according to "Functional Specification Rev. 3.0 */
if (l2h->uid_len != 7)
return NULL;
@@ -138,6 +165,7 @@ const struct rfid_protocol rfid_protocol_mful = {
.read = &mful_read,
.write = &mful_write,
.fini = &mful_fini,
+ .getopt = &mful_getopt,
},
};
diff --git a/src/rfid_proto_tcl.c b/src/rfid_proto_tcl.c
index af626c6..70259e6 100644
--- a/src/rfid_proto_tcl.c
+++ b/src/rfid_proto_tcl.c
@@ -781,6 +781,8 @@ tcl_getopt(struct rfid_protocol_handle *h, int optname, void *optval,
*optlen = sizeof(u_int8_t);
*opt_str = h->priv.tcl.ats_len & 0xff;
break;
+ default:
+ return -EINVAL;
}
return 0;
diff --git a/src/rfid_protocol.c b/src/rfid_protocol.c
index 99fc8b1..3cbe8af 100644
--- a/src/rfid_protocol.c
+++ b/src/rfid_protocol.c
@@ -114,7 +114,6 @@ rfid_protocol_getopt(struct rfid_protocol_handle *ph, int optname,
unsigned char *optchar = optval;
switch (optname) {
- break;
default:
return -EINVAL;
break;
diff --git a/utils/librfid-tool.c b/utils/librfid-tool.c
index 37efadc..be6e843 100644
--- a/utils/librfid-tool.c
+++ b/utils/librfid-tool.c
@@ -260,6 +260,9 @@ static int l2_by_name(const char *name)
static void do_scan(void)
{
int rc;
+ unsigned int size;
+ unsigned int size_len = sizeof(size);
+
printf("scanning for RFID token...\n");
rc = rfid_scan(rh, &l2h, &ph);
if (rc >= 2) {
@@ -272,6 +275,10 @@ static void do_scan(void)
}
if (rc >= 3) {
printf("Protocol success (%s)\n", rfid_protocol_name(ph));
+
+ if (rfid_protocol_getopt(ph, RFID_OPT_PROTO_SIZE,
+ &size, &size_len) == 0)
+ printf("Size: %u bytes\n", size);
}
}
personal git repositories of Harald Welte. Your mileage may vary