summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2006-06-23 20:26:40 +0000
committerlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2006-06-23 20:26:40 +0000
commit7a398f0b121d787ffc45d1371aa5f6e438576e9b (patch)
tree3e8623ddbe6dd5b42189268eaeaaaaf846f574a6
parent23f5e7e37a16f05fda562f9c1208fb63c5dc9996 (diff)
fix TX chaining: Don't use/respect toggle bit (block nr) for S-blocks.
git-svn-id: https://svn.gnumonks.org/trunk/librfid@1831 e0336214-984f-0b4b-a45f-81c69e1f0ede
-rw-r--r--include/librfid/rfid.h2
-rw-r--r--pegoda/pegoda.c14
-rw-r--r--src/rfid_proto_tcl.c40
3 files changed, 35 insertions, 21 deletions
diff --git a/include/librfid/rfid.h b/include/librfid/rfid.h
index 76e86e3..b1943d7 100644
--- a/include/librfid/rfid.h
+++ b/include/librfid/rfid.h
@@ -11,7 +11,7 @@ enum rfid_frametype {
RFID_MIFARE_FRAME,
};
-#if 0
+#if 1
#define DEBUGP(x, args ...) fprintf(stderr, "%s(%d):%s: " x, __FILE__, __LINE__, __FUNCTION__, ## args)
#define DEBUGPC(x, args ...) fprintf(stderr, x, ## args)
#else
diff --git a/pegoda/pegoda.c b/pegoda/pegoda.c
index f391d62..8b73755 100644
--- a/pegoda/pegoda.c
+++ b/pegoda/pegoda.c
@@ -118,7 +118,7 @@ int pegoda_transceive(struct pegoda_handle *ph,
memcpy(rx, rxbuf+sizeof(*rxhdr), rc-sizeof(*rxhdr));
- return 0;
+ return rxhdr->cmd;
}
struct pegoda_handle *pegoda_open(void)
@@ -253,6 +253,7 @@ int main(int argc, char **argv)
unsigned char rbuf[256];
unsigned int rlen = sizeof(rbuf);
struct pegoda_handle *ph;
+ int i;
ph = pegoda_open();
if (!ph)
@@ -284,9 +285,14 @@ int main(int argc, char **argv)
pegoda_transceive(ph, PEGODA_CMD_PICC_CASC_SELECT,
buf, 5, rbuf, &rlen);
- pegoda_auth_key(ph, 0, "\xff\xff\xff\xff\xff\xff");
- pegoda_read16(ph, 0, rbuf);
- printf("read16 = %s\n", hexdump(rbuf, 16));
+ for (i = 0; i < 16; i++) {
+ int j;
+ pegoda_auth_key(ph, i, "\xff\xff\xff\xff\xff\xff");
+ for (j = 0; j < 4; j++) {
+ pegoda_read16(ph, (i*4)+j, rbuf);
+ printf("read16[%u:%u] = %s\n", i,j,hexdump(rbuf, 16));
+ }
+ }
exit(0);
}
diff --git a/src/rfid_proto_tcl.c b/src/rfid_proto_tcl.c
index 64f28b3..4a92c62 100644
--- a/src/rfid_proto_tcl.c
+++ b/src/rfid_proto_tcl.c
@@ -38,6 +38,10 @@
#define RFID_MAX_FRAMELEN 256
+#define is_s_block(x) ((x & 0xc0) == 0xc0)
+#define is_r_block(x) ((x & 0xc0) == 0x80)
+#define is_i_block(x) ((x & 0xc0) == 0x00)
+
static enum rfid_frametype l2_to_frame(unsigned int layer2)
{
switch (layer2) {
@@ -319,13 +323,15 @@ tcl_build_prologue2(struct tcl_handle *th,
*prlg = pcb;
- if (th->toggle) {
- /* we've sent a toggle bit last time */
- th->toggle = 0;
- } else {
- /* we've not sent a toggle last time: send one */
- th->toggle = 1;
- *prlg |= 0x01;
+ if (!is_s_block(pcb)) {
+ if (th->toggle) {
+ /* we've sent a toggle bit last time */
+ th->toggle = 0;
+ } else {
+ /* we've not sent a toggle last time: send one */
+ th->toggle = 1;
+ *prlg |= 0x01;
+ }
}
if (th->flags & TCL_HANDLE_F_CID_USED) {
@@ -496,10 +502,6 @@ tcl_deselect(struct rfid_protocol_handle *h)
return 0;
}
-#define is_s_block(x) ((x & 0xc0) == 0xc0)
-#define is_r_block(x) ((x & 0xc0) == 0x80)
-#define is_i_block(x) ((x & 0xc0) == 0x00)
-
struct fr_buff {
unsigned int frame_len; /* length of frame */
unsigned int hdr_len; /* length of header within frame */
@@ -634,14 +636,14 @@ do_tx:
if (ret < 0)
goto out;
- if ((xcvb.rx.data[0] & 0x01) != h->priv.tcl.toggle) {
- DEBUGP("response with wrong toggle bit\n");
- goto out;
- }
-
if (is_r_block(xcvb.rx.data[0])) {
DEBUGP("R-Block\n");
+ if ((xcvb.rx.data[0] & 0x01) != h->priv.tcl.toggle) {
+ DEBUGP("response with wrong toggle bit\n");
+ goto out;
+ }
+
/* Handle ACK frame in case of chaining */
if (!check_cid(th, &xcvb))
goto out;
@@ -687,6 +689,12 @@ do_tx:
/* we're actually receiving payload data */
DEBUGP("I-Block: ");
+
+ if ((xcvb.rx.data[0] & 0x01) != h->priv.tcl.toggle) {
+ DEBUGP("response with wrong toggle bit\n");
+ goto out;
+ }
+
xcvb.rx.hdr_len = 1;
if (!check_cid(th, &xcvb))
personal git repositories of Harald Welte. Your mileage may vary