+
+ if(trigger) LED_A_ON();
+
+ if (tracing) LogTrace(cmd, len, 0, 0, NULL, TRUE);
+}
+
+/* Sends an APDU to the tag
+ * TODO: check CRC and preamble
+ */
+uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response)
+{
+ uint8_t crc[2] = {0x00, 0x00};
+ uint8_t message_frame[message_length + 4];
+ // PCB
+ message_frame[0] = 0x0A | pcb_blocknum;
+ pcb_blocknum ^= 1;
+ // CID
+ message_frame[1] = 0;
+ // INF
+ memcpy(message_frame + 2, message, message_length);
+ // EDC (CRC)
+ ComputeCrc14443(CRC_14443_B, message_frame, message_length + 2, &message_frame[message_length + 2], &message_frame[message_length + 3]);
+ // send
+ CodeAndTransmit14443bAsReader(message_frame, message_length + 4);
+ // get response
+ GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+ if(Demod.len < 3)
+ return 0;
+
+ // VALIDATE CRC
+ ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]);
+ if ( crc[0] != Demod.output[Demod.len-2] || crc[1] != Demod.output[Demod.len-1] )
+ return 0;
+
+ // copy response contents
+ if(response != NULL)
+ memcpy(response, Demod.output, Demod.len);
+
+ return Demod.len;
+}
+
+/**
+* SRx Initialise.
+*/
+uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card )
+{
+ // INITIATE command: wake up the tag using the INITIATE
+ static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
+ // SELECT command (with space for CRC)
+ uint8_t select_srx[] = { ISO14443B_SELECT, 0x00, 0x00, 0x00};
+ // temp to calc crc.
+ uint8_t crc[2] = {0x00, 0x00};
+
+ CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx));
+ GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+
+ if (Demod.len == 0) return 2;
+
+ // Randomly generated Chip ID
+ if (card) card->chipid = Demod.output[0];
+
+ select_srx[1] = Demod.output[0];
+
+ ComputeCrc14443(CRC_14443_B, select_srx, 2, &select_srx[2], &select_srx[3]);
+ CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx));
+ GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+
+ if (Demod.len != 3) return 2;
+
+ // Check the CRC of the answer:
+ ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2 , &crc[0], &crc[1]);
+ if(crc[0] != Demod.output[1] || crc[1] != Demod.output[2]) return 3;
+
+ // Check response from the tag: should be the same UID as the command we just sent:
+ if (select_srx[1] != Demod.output[0]) return 1;
+
+ // First get the tag's UID:
+ select_srx[0] = ISO14443B_GET_UID;
+
+ ComputeCrc14443(CRC_14443_B, select_srx, 1 , &select_srx[1], &select_srx[2]);
+ CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one
+ GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+
+ if (Demod.len != 10) return 2;
+
+ // The check the CRC of the answer
+ ComputeCrc14443(CRC_14443_B, Demod.output, Demod.len-2, &crc[0], &crc[1]);
+ if(crc[0] != Demod.output[8] || crc[1] != Demod.output[9]) return 3;
+
+ if (card) {
+ card->uidlen = 8;
+ memcpy(card->uid, Demod.output, 8);