- 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
This commit is contained in:
laforge 2006-12-01 13:29:00 +00:00
parent 8b39e78b9d
commit f0a3a3f8c4
9 changed files with 101 additions and 9 deletions

View File

@ -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 {

View File

@ -45,6 +45,7 @@ enum rfid_protocol_id {
enum rfid_protocol_opt {
RFID_OPT_PROTO_ID,
RFID_OPT_PROTO_SIZE = 0x10000001,
};
#ifdef __LIBRFID__

View File

@ -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;

View File

@ -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,
},
};

View File

@ -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,
},
};

View File

@ -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,
},
};

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}