- 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:
parent
8b39e78b9d
commit
f0a3a3f8c4
|
@ -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 {
|
||||
|
|
|
@ -45,6 +45,7 @@ enum rfid_protocol_id {
|
|||
|
||||
enum rfid_protocol_opt {
|
||||
RFID_OPT_PROTO_ID,
|
||||
RFID_OPT_PROTO_SIZE = 0x10000001,
|
||||
};
|
||||
|
||||
#ifdef __LIBRFID__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue