+ return 2;
+ default: break;
+ }
+ PrintAndLog(" UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
+ legic_print_type(card.cardsize, 0);
+ return 0;
+}
+int CmdLegicReader(const char *Cmd){
+ return HFLegicReader(Cmd, TRUE);
+}
+
+int CmdLegicDump(const char *Cmd){
+
+ FILE *f;
+ char filename[FILE_PATH_SIZE] = {0x00};
+ char *fnameptr = filename;
+ size_t fileNlen = 0;
+ bool errors = false;
+ uint16_t dumplen;
+ uint8_t cmdp = 0;
+
+ memset(filename, 0, sizeof(filename));
+
+ while(param_getchar(Cmd, cmdp) != 0x00) {
+ switch(param_getchar(Cmd, cmdp)) {
+ case 'h':
+ case 'H':
+ return usage_legic_dump();
+ case 'o':
+ case 'O':
+ fileNlen = param_getstr(Cmd, cmdp+1, filename);
+ if (!fileNlen)
+ errors = true;
+ if (fileNlen > FILE_PATH_SIZE-5)
+ fileNlen = FILE_PATH_SIZE-5;
+ cmdp += 2;
+ break;
+ default:
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+ errors = true;
+ break;
+ }
+ if(errors) break;
+ }
+
+ //Validations
+ if(errors) return usage_legic_dump();
+
+ // tagtype
+ legic_card_select_t card;
+ if (legic_get_type(&card)) {
+ PrintAndLog("Failed to identify tagtype");
+ return -1;
+ }
+ dumplen = card.cardsize;
+
+ legic_print_type(dumplen, 0);
+ PrintAndLog("Reading tag memory...");
+
+ UsbCommand c = {CMD_READER_LEGIC_RF, {0x00, dumplen, 0x55}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ UsbCommand resp;
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) {
+ PrintAndLog("Command execute time-out");
+ return 1;
+ }
+
+ uint8_t isOK = resp.arg[0] & 0xFF;
+ if ( !isOK ) {
+ PrintAndLog("Failed dumping tag data");
+ return 2;
+ }
+
+ uint16_t readlen = resp.arg[1];
+ uint8_t *data = malloc(readlen);
+ if (!data) {
+ PrintAndLog("Fail, cannot allocate memory");
+ return 3;
+ }
+ memset(data, 0, readlen);
+
+ if ( readlen != dumplen )
+ PrintAndLog("Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen);
+
+ // copy data from device
+ GetEMLFromBigBuf(data, readlen, 0);
+ if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500)) {
+ PrintAndLog("Fail, transfer from device time-out");
+ free(data);
+ return 4;
+ }
+
+ // user supplied filename?
+ if (fileNlen < 1)
+ sprintf(fnameptr,"%02X%02X%02X%02X.bin", data[0], data[1], data[2], data[3]);
+ else
+ sprintf(fnameptr + fileNlen,".bin");
+
+ f = fopen(filename,"wb");
+ if (!f) {
+ PrintAndLog("Could not create file name %s", filename);
+ if (data)
+ free(data);
+ return 5;
+ }
+ fwrite(data, 1, readlen, f);
+ fclose(f);
+ free(data);
+ PrintAndLog("Wrote %d bytes to %s", readlen, filename);
+ return 0;
+}
+
+int CmdLegicRestore(const char *Cmd){
+
+ FILE *f;
+ char filename[FILE_PATH_SIZE] = {0x00};
+ char *fnameptr = filename;
+ size_t fileNlen = 0;
+ bool errors = true;
+ uint16_t numofbytes;
+ uint8_t cmdp = 0;
+
+ memset(filename, 0, sizeof(filename));
+
+ while(param_getchar(Cmd, cmdp) != 0x00) {
+ switch(param_getchar(Cmd, cmdp)) {
+ case 'h':
+ case 'H':
+ errors = true;
+ break;
+ case 'i':
+ case 'I':
+ fileNlen = param_getstr(Cmd, cmdp+1, filename);
+ if (!fileNlen)
+ errors = true;
+ else
+ errors = false;
+
+ if (fileNlen > FILE_PATH_SIZE-5)
+ fileNlen = FILE_PATH_SIZE-5;
+ cmdp += 2;
+ break;
+ default:
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+ errors = true;
+ break;
+ }
+ if (errors) break;
+ }
+
+ //Validations
+ if(errors) return usage_legic_restore();
+
+ // tagtype
+ legic_card_select_t card;
+ if (legic_get_type(&card)) {
+ PrintAndLog("Failed to identify tagtype");
+ return 1;
+ }
+ numofbytes = card.cardsize;
+
+ // set up buffer
+ uint8_t *data = malloc(numofbytes);
+ if (!data) {
+ PrintAndLog("Fail, cannot allocate memory");
+ return 2;
+ }
+ memset(data, 0, numofbytes);
+
+ legic_print_type(numofbytes, 0);
+
+ // set up file
+ fnameptr += fileNlen;
+ sprintf(fnameptr, ".bin");
+
+ f = fopen(filename,"rb");
+ if (!f) {
+ PrintAndLog("File %s not found or locked", filename);
+ return 3;
+ }
+
+ // verify size of dumpfile is the same as card.
+ fseek(f, 0, SEEK_END); // seek to end of file
+ size_t filesize = ftell(f); // get current file pointer
+ fseek(f, 0, SEEK_SET); // seek back to beginning of file
+
+ if ( filesize != numofbytes) {
+ PrintAndLog("Fail, filesize and cardsize is not equal. [%u != %u]", filesize, numofbytes);
+ free(data);
+ fclose(f);
+ return 4;
+ }
+
+ // load file
+ size_t bytes_read = fread(data, 1, numofbytes, f);
+ fclose(f);
+
+ if ( bytes_read == 0){
+ PrintAndLog("File reading error");
+ free(data);
+ return 2;
+ }
+
+ PrintAndLog("Restoring to card");
+
+ // transfer to device
+ size_t len = 0;
+ UsbCommand c = {CMD_WRITER_LEGIC_RF, {0, 0, 0x55}};
+ UsbCommand resp;
+ for(size_t i = 7; i < numofbytes; i += USB_CMD_DATA_SIZE) {
+
+ len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
+ c.arg[0] = i; // offset
+ c.arg[1] = len; // number of bytes
+ memcpy(c.d.asBytes, data+i, len);
+ clearCommandBuffer();
+ SendCommand(&c);
+
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) {
+ PrintAndLog("command execution time out");
+ free(data);