+/**
+ * Commandline handling: HF15 CMD SYSINFO
+ * get system information from tag/VICC
+ */
+int CmdHF15CmdSysinfo(const char *Cmd) {
+ UsbCommand resp;
+ uint8_t *recv;
+ UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
+ uint8_t *req=c.d.asBytes;
+ int reqlen=0;
+ char cmdbuf[100];
+ char *cmd=cmdbuf;
+ char output[2048]="";
+ int i;
+
+ strncpy(cmd,Cmd,99);
+
+ // usage:
+ if (strlen(cmd)<1) {
+ PrintAndLog("Usage: hf 15 cmd sysinfo [options] <uid|s|u|*>");
+ PrintAndLog(" options:");
+ PrintAndLog(" -2 use slower '1 out of 256' mode");
+ PrintAndLog(" uid (either): ");
+ PrintAndLog(" <8B hex> full UID eg E011223344556677");
+ PrintAndLog(" s selected tag");
+ PrintAndLog(" u unaddressed mode");
+ PrintAndLog(" * scan for tag");
+ PrintAndLog(" start#: page number to start 0-255");
+ PrintAndLog(" count#: number of pages");
+ return 0;
+ }
+
+ prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15693_GET_SYSTEM_INFO},1);
+ reqlen=c.arg[0];
+
+ reqlen=AddCrc(req,reqlen);
+ c.arg[0]=reqlen;
+
+ SendCommand(&c);
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+ recv = resp.d.asBytes;
+ if (ISO15693_CRC_CHECK==Crc(recv,resp.arg[0])) {
+ if (!(recv[0] & ISO15693_RES_ERROR)) {
+ *output=0; // reset outputstring
+ PrintAndLog("UID: %s", sprintUID(NULL,recv+2));
+ PrintAndLog("Manufacturer byte: %02X, %s", recv[8], getManufacturerName(recv[8]));
+ PrintAndLog("Chip ID: %02X, %s", recv[7], getChipInfo(recv[8], recv[7]));
+ i=10;
+ if (recv[1] & 0x01)
+ sprintf(output+strlen(output),"DSFID supported, set to %02X\n\r",recv[i++]);
+ else
+ strcat(output,"DSFID not supported\n\r");
+ if (recv[1] & 0x02)
+ sprintf(output+strlen(output),"AFI supported, set to %03X\n\r",recv[i++]);
+ else
+ strcat(output,"AFI not supported\n\r");
+ if (recv[1] & 0x04) {
+ strcat(output,"Tag provides info on memory layout (vendor dependent)\n\r");
+ sprintf(output+strlen(output)," %i (or %i) bytes/page x %i pages \n\r",
+ (recv[i+1]&0x1F)+1, (recv[i+1]&0x1F), recv[i]+1);
+ i+=2;
+ } else
+ strcat(output,"Tag does not provide information on memory layout\n\r");
+ if (recv[1] & 0x08) sprintf(output+strlen(output),"IC reference given: %02X\n\r",recv[i++]);
+ else strcat(output,"IC reference not given\n\r");
+
+
+ PrintAndLog("%s",output);
+ } else {
+ PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
+ }
+ } else {
+ PrintAndLog("CRC failed");
+ }
+ } else {
+ PrintAndLog("timeout: no answer");
+ }
+
+ return 0;
+}
+
+/**
+ * Commandline handling: HF15 CMD READMULTI
+ * Read multiple blocks at once (not all tags support this)
+ */
+int CmdHF15CmdReadmulti(const char *Cmd) {
+ UsbCommand resp;
+ uint8_t *recv;
+ UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
+ uint8_t *req=c.d.asBytes;
+ int reqlen=0, pagenum,pagecount;
+ char cmdbuf[100];
+ char *cmd=cmdbuf;
+ char output[2048]="";
+
+ strncpy(cmd,Cmd,99);
+
+ // usage:
+ if (strlen(cmd)<3) {
+ PrintAndLog("Usage: hf 15 cmd readmulti [options] <uid|s|u|*> <start#> <count#>");
+ PrintAndLog(" options:");
+ PrintAndLog(" -2 use slower '1 out of 256' mode");
+ PrintAndLog(" uid (either): ");
+ PrintAndLog(" <8B hex> full UID eg E011223344556677");
+ PrintAndLog(" s selected tag");
+ PrintAndLog(" u unaddressed mode");
+ PrintAndLog(" * scan for tag");
+ PrintAndLog(" start#: page number to start 0-255");
+ PrintAndLog(" count#: number of pages");
+ return 0;
+ }
+
+ prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15693_READ_MULTI_BLOCK},1);
+ reqlen=c.arg[0];
+
+ pagenum=strtol(cmd,NULL,0);
+
+ // skip to next space
+ while (*cmd!=' ' && *cmd!='\t') cmd++;
+ // skip over the space
+ while (*cmd==' ' || *cmd=='\t') cmd++;
+
+ pagecount=strtol(cmd,NULL,0);
+ if (pagecount>0) pagecount--; // 0 means 1 page, 1 means 2 pages, ...
+
+ req[reqlen++]=(uint8_t)pagenum;
+ req[reqlen++]=(uint8_t)pagecount;
+
+ reqlen=AddCrc(req,reqlen);
+
+ c.arg[0]=reqlen;