From: Harald Welte Date: Sun, 23 Oct 2005 22:01:39 +0000 (+0000) Subject: - handle reception of chained frames correctly X-Git-Url: http://git.rot13.org/?a=commitdiff_plain;h=ce0240b0ed347fabd7844c351a1bf466d5167ea2;p=librfid - handle reception of chained frames correctly - workaround to RC632 problem: asic doesn't remove crc bytes at end of frame ?!? git-svn-id: https://svn.gnumonks.org/trunk/librfid@1560 e0336214-984f-0b4b-a45f-81c69e1f0ede --- diff --git a/openct-escape.c b/openct-escape.c index 628aded..92a8f94 100644 --- a/openct-escape.c +++ b/openct-escape.c @@ -147,7 +147,7 @@ static int select_mf(void) } -static int get_challenge(unsigned char len) +static int iso7816_get_challenge(unsigned char len) { unsigned char cmd[] = { 0x00, 0x84, 0x00, 0x00, 0x08 }; unsigned char ret[256]; @@ -161,7 +161,7 @@ static int get_challenge(unsigned char len) if (rv < 0) return rv; - //printf("%s\n", rfid_hexdump(ret, rlen)); + printf("%d: [%s]\n", rlen, rfid_hexdump(ret, rlen)); return 0; } @@ -181,6 +181,8 @@ iso7816_select_application(void) return rv; /* FIXME: parse response */ + printf("%s\n", rfid_hexdump(resp, rlen)); + return 0; } @@ -201,6 +203,7 @@ iso7816_select_ef(u_int16_t fid) return rv; /* FIXME: parse response */ + printf("%s\n", rfid_hexdump(resp, rlen)); return 0; } @@ -325,9 +328,9 @@ int main(int argc, char **argv) iso7816_select_application(); iso7816_select_ef(0x011e); iso7816_select_ef(0x0101); -#if 0 +#if 1 for (i = 0; i < 4; i++) - get_challenge(0x60); + iso7816_get_challenge(0x60); #endif break; case RFID_PROTOCOL_MIFARE_UL: diff --git a/rfid_proto_tcl.c b/rfid_proto_tcl.c index 8590fd4..2451b1d 100644 --- a/rfid_proto_tcl.c +++ b/rfid_proto_tcl.c @@ -459,6 +459,10 @@ tcl_transcieve(struct rfid_protocol_handle *h, { int ret; unsigned char *tx_buf, *rx_buf; + unsigned char *_rx_data = rx_data; + unsigned int _rx_len; + unsigned int max_rx_len = *rx_len; /* maximum number of payoload that + caller has requested */ unsigned int prlg_len; struct tcl_handle *th = &h->priv.tcl; @@ -494,15 +498,20 @@ tcl_transcieve(struct rfid_protocol_handle *h, _tx = tx_buf; _tx_len = tx_len+prlg_len; _timeout = th->fwt; + _rx_len = *rx_len; + *rx_len = 0; do_tx: ret = h->l2h->l2->fn.transcieve(h->l2h, RFID_14443A_FRAME_REGULAR, _tx, _tx_len, - rx_buf, rx_len, _timeout, 0); + rx_buf, &_rx_len, _timeout, 0); DEBUGP("l2 transcieve finished\n"); if (ret < 0) goto out_rxb; + if (_rx_len >= 2) + _rx_len -= 2; /* CRC is not removed by ASIC ?!? */ + if ((*rx_buf & 0x01) != h->priv.tcl.toggle) { DEBUGP("response with wrong toggle bit\n"); goto out_rxb; @@ -544,7 +553,7 @@ do_tx: DEBUGP("S-Block\n"); /* Handle Wait Time Extension */ if (*rx_buf & TCL_PCB_CID_FOLLOWING) { - if (*rx_len < 3) { + if (_rx_len < 3) { DEBUGP("S-Block with CID but short len\n"); ret = -1; goto out_rxb; @@ -584,6 +593,7 @@ do_tx: } else if (is_i_block(*rx_buf)) { unsigned char *inf = rx_buf+1; + unsigned int net_payload_len; /* we're actually receiving payload data */ DEBUGP("I-Block\n"); @@ -597,7 +607,11 @@ do_tx: if (*rx_buf & TCL_PCB_NAD_FOLLOWING) { inf++; } - memcpy(rx_data, inf, *rx_len - (inf - rx_buf)); + net_payload_len = _rx_len - (inf - rx_buf); + memcpy(_rx_data, inf, net_payload_len); + /* increment the number of payload bytes that we actually received */ + *rx_len += net_payload_len; + _rx_data += net_payload_len; if (*rx_buf & 0x10) { /* we're not the last frame in the chain, continue rx */