-//-----------------------------------------------------------------------------
-// Read an ISO 14443a tag. Send out commands and store answers.
-//
-//-----------------------------------------------------------------------------
-void ReaderIso14443a(DWORD parameter)
-{
- // Anticollision
- BYTE wupa[] = { 0x52 };
- BYTE sel_all[] = { 0x93,0x20 };
- BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
- BYTE sel_all_c2[] = { 0x95,0x20 };
- BYTE sel_uid_c2[] = { 0x95,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
+/* performs iso14443a anticolision procedure
+ * fills the uid pointer unless NULL
+ * fills resp_data unless NULL */
+int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data) {
+ uint8_t wupa[] = { 0x52 };
+ uint8_t sel_all[] = { 0x93,0x20 };
+ uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
+ uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
+
+ uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
+ uint8_t* uid = resp + 7;
+
+ uint8_t sak = 0x04; // cascade uid
+ int cascade_level = 0;
+
+ int len;
+
+ // Broadcast for a card, WUPA (0x52) will force response from all cards in the field
+ ReaderTransmitShort(wupa);
+ // Receive the ATQA
+ if(!ReaderReceive(resp)) return 0;
+
+ if(resp_data)
+ memcpy(resp_data->atqa, resp, 2);
+
+ ReaderTransmit(sel_all,sizeof(sel_all));
+ if(!ReaderReceive(uid)) return 0;
+
+ // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
+ // which case we need to make a cascade 2 request and select - this is a long UID
+ // While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
+ for(; sak & 0x04; cascade_level++)
+ {
+ // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
+ sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
+
+ // SELECT_ALL
+ ReaderTransmit(sel_all,sizeof(sel_all));
+ if (!ReaderReceive(resp)) return 0;
+ if(uid_ptr) memcpy(uid_ptr + cascade_level*4, resp, 4);