+
+
+// Since there is no standardized way of reading the AFI out of a tag, we will brute force it
+// (some manufactures offer a way to read the AFI, though)
+void BruteforceIso15693Afi(uint32_t speed)
+{
+ uint8_t data[20];
+ uint8_t *recv=data;
+ int datalen=0, recvlen=0;
+
+ Iso15693InitReader();
+
+ // first without AFI
+ // Tags should respond wihtout AFI and with AFI=0 even when AFI is active
+
+ data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
+ ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
+ data[1]=ISO15_CMD_INVENTORY;
+ data[2]=0; // mask length
+ datalen=AddCrc(data,3);
+ recvlen=SendDataTag(data,datalen,0,speed,&recv);
+ WDT_HIT();
+ if (recvlen>=12) {
+ Dbprintf("NoAFI UID=%s",sprintUID(NULL,&recv[2]));
+ }
+
+ // now with AFI
+
+ data[0]=ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
+ ISO15_REQ_INVENTORY | ISO15_REQINV_AFI | ISO15_REQINV_SLOT1;
+ data[1]=ISO15_CMD_INVENTORY;
+ data[2]=0; // AFI
+ data[3]=0; // mask length
+
+ for (int i=0;i<256;i++) {
+ data[2]=i & 0xFF;
+ datalen=AddCrc(data,4);
+ recvlen=SendDataTag(data,datalen,0,speed,&recv);
+ WDT_HIT();
+ if (recvlen>=12) {
+ Dbprintf("AFI=%i UID=%s",i,sprintUID(NULL,&recv[2]));
+ }
+ }
+ Dbprintf("AFI Bruteforcing done.");
+
+}
+
+// Allows to directly send commands to the tag via the client
+void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
+
+ int recvlen=0;
+ uint8_t *recvbuf=(uint8_t *)BigBuf;
+// UsbCommand n;
+
+ if (DEBUG) {
+ Dbprintf("SEND");
+ Dbhexdump(datalen,data,true);
+ }
+
+ recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
+
+ if (recv) {
+ LED_B_ON();
+ cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
+ LED_B_OFF();
+
+ if (DEBUG) {
+ Dbprintf("RECV");
+ DbdecodeIso15693Answer(recvlen,recvbuf);
+ Dbhexdump(recvlen,recvbuf,true);
+ }
+ }
+
+}
+
+
+
+
+// --------------------------------------------------------------------
+// -- Misc & deprecated functions
+// --------------------------------------------------------------------
+
+/*
+
+// do not use; has a fix UID
+static void __attribute__((unused)) BuildSysInfoRequest(uint8_t *uid)
+{
+ uint8_t cmd[12];
+
+ uint16_t crc;
+ // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
+ // followed by teh block data
+ // one sub-carrier, inventory, 1 slot, fast rate
+ cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
+ // System Information command code
+ cmd[1] = 0x2B;
+ // UID may be optionally specified here
+ // 64-bit UID
+ cmd[2] = 0x32;
+ cmd[3]= 0x4b;
+ cmd[4] = 0x03;
+ cmd[5] = 0x01;
+ cmd[6] = 0x00;
+ cmd[7] = 0x10;
+ cmd[8] = 0x05;
+ cmd[9]= 0xe0; // always e0 (not exactly unique)
+ //Now the CRC
+ crc = Crc(cmd, 10); // the crc needs to be calculated over 2 bytes
+ cmd[10] = crc & 0xff;
+ cmd[11] = crc >> 8;
+
+ CodeIso15693AsReader(cmd, sizeof(cmd));
+}
+
+
+// do not use; has a fix UID
+static void __attribute__((unused)) BuildReadMultiBlockRequest(uint8_t *uid)
+{
+ uint8_t cmd[14];
+
+ uint16_t crc;
+ // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
+ // followed by teh block data
+ // one sub-carrier, inventory, 1 slot, fast rate
+ cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
+ // READ Multi BLOCK command code
+ cmd[1] = 0x23;
+ // UID may be optionally specified here
+ // 64-bit UID
+ cmd[2] = 0x32;
+ cmd[3]= 0x4b;
+ cmd[4] = 0x03;
+ cmd[5] = 0x01;
+ cmd[6] = 0x00;
+ cmd[7] = 0x10;
+ cmd[8] = 0x05;
+ cmd[9]= 0xe0; // always e0 (not exactly unique)
+ // First Block number to read
+ cmd[10] = 0x00;
+ // Number of Blocks to read
+ cmd[11] = 0x2f; // read quite a few
+ //Now the CRC
+ crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
+ cmd[12] = crc & 0xff;
+ cmd[13] = crc >> 8;
+
+ CodeIso15693AsReader(cmd, sizeof(cmd));
+}
+
+// do not use; has a fix UID
+static void __attribute__((unused)) BuildArbitraryRequest(uint8_t *uid,uint8_t CmdCode)
+{
+ uint8_t cmd[14];
+
+ uint16_t crc;
+ // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
+ // followed by teh block data
+ // one sub-carrier, inventory, 1 slot, fast rate
+ cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
+ // READ BLOCK command code
+ cmd[1] = CmdCode;
+ // UID may be optionally specified here
+ // 64-bit UID
+ cmd[2] = 0x32;
+ cmd[3]= 0x4b;
+ cmd[4] = 0x03;
+ cmd[5] = 0x01;
+ cmd[6] = 0x00;
+ cmd[7] = 0x10;
+ cmd[8] = 0x05;
+ cmd[9]= 0xe0; // always e0 (not exactly unique)
+ // Parameter
+ cmd[10] = 0x00;
+ cmd[11] = 0x0a;
+
+// cmd[12] = 0x00;
+// cmd[13] = 0x00; //Now the CRC
+ crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
+ cmd[12] = crc & 0xff;
+ cmd[13] = crc >> 8;
+
+ CodeIso15693AsReader(cmd, sizeof(cmd));
+}
+
+// do not use; has a fix UID
+static void __attribute__((unused)) BuildArbitraryCustomRequest(uint8_t uid[], uint8_t CmdCode)
+{
+ uint8_t cmd[14];
+
+ uint16_t crc;
+ // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
+ // followed by teh block data
+ // one sub-carrier, inventory, 1 slot, fast rate
+ cmd[0] = (1 << 5) | (1 << 1); // no SELECT bit
+ // READ BLOCK command code
+ cmd[1] = CmdCode;
+ // UID may be optionally specified here
+ // 64-bit UID
+ cmd[2] = 0x32;
+ cmd[3]= 0x4b;
+ cmd[4] = 0x03;
+ cmd[5] = 0x01;
+ cmd[6] = 0x00;
+ cmd[7] = 0x10;
+ cmd[8] = 0x05;
+ cmd[9]= 0xe0; // always e0 (not exactly unique)
+ // Parameter
+ cmd[10] = 0x05; // for custom codes this must be manufcturer code
+ cmd[11] = 0x00;
+
+// cmd[12] = 0x00;
+// cmd[13] = 0x00; //Now the CRC
+ crc = Crc(cmd, 12); // the crc needs to be calculated over 2 bytes
+ cmd[12] = crc & 0xff;
+ cmd[13] = crc >> 8;
+
+ CodeIso15693AsReader(cmd, sizeof(cmd));
+}
+
+
+
+
+*/
+
+