+ 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);
+ if ( bytes_read == 0){
+ PrintAndLog("File reading error");
+ free(data);
+ fclose(f);
+ return 2;
+ }
+ fclose(f);
+
+ 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);
+ return 1;
+ }
+ uint8_t isOK = resp.arg[0] & 0xFF;
+ if ( !isOK ) {
+ PrintAndLog("failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
+ free(data);
+ return 1;
+ }
+ PrintAndLog("Wrote chunk [offset %d | len %d | total %d", i, len, i+len);
+ }
+
+ free(data);
+ PrintAndLog("\nWrote %d bytes to card from file %s", numofbytes, filename);
+ return 0;
+}
+
+int CmdLegicELoad(const char *Cmd) {
+ FILE * f;
+ char filename[FILE_PATH_SIZE];
+ char *fnameptr = filename;
+ int len, numofbytes;
+ int nameParamNo = 1;
+
+ char cmdp = param_getchar(Cmd, 0);
+ if ( cmdp == 'h' || cmdp == 'H' || cmdp == 0x00)
+ return usage_legic_eload();
+
+ switch (cmdp) {
+ case '0' : numofbytes = 22; break;
+ case '1' :
+ case '\0': numofbytes = 256; break;
+ case '2' : numofbytes = 1024; break;
+ default : numofbytes = 256; nameParamNo = 0;break;
+ }
+
+ // set up buffer
+ uint8_t *data = malloc(numofbytes);
+ if (!data) {
+ PrintAndLog("Fail, cannot allocate memory");
+ return 3;
+ }
+ memset(data, 0, numofbytes);
+
+ // set up file
+ len = param_getstr(Cmd, nameParamNo, filename);
+ if (len > FILE_PATH_SIZE - 5)
+ len = FILE_PATH_SIZE - 5;
+ fnameptr += len;
+ sprintf(fnameptr, ".bin");
+
+ // open file
+ if ((f = fopen(filename,"rb")) == NULL) {
+ PrintAndLog("File %s not found or locked", filename);
+ free(data);
+ return 1;
+ }
+
+ // load file
+ size_t bytes_read = fread(data, 1, numofbytes, f);
+ if ( bytes_read == 0){
+ PrintAndLog("File reading error");
+ free(data);
+ fclose(f);
+ return 2;
+ }
+ fclose(f);
+
+ // transfer to device
+ legic_seteml(data, 0, numofbytes);
+
+ free(data);
+ PrintAndLog("\nLoaded %d bytes from file: %s to emulator memory", numofbytes, filename);
+ return 0;
+}
+
+int CmdLegicESave(const char *Cmd) {
+ FILE *f;
+ char filename[FILE_PATH_SIZE];
+ char *fnameptr = filename;
+ int fileNlen, numofbytes, nameParamNo = 1;
+
+ memset(filename, 0, sizeof(filename));
+
+ char cmdp = param_getchar(Cmd, 0);
+
+ if ( cmdp == 'h' || cmdp == 'H' || cmdp == 0x00)
+ return usage_legic_esave();
+
+ switch (cmdp) {
+ case '0' : numofbytes = 22; break;
+ case '1' :
+ case '\0': numofbytes = 256; break;
+ case '2' : numofbytes = 1024; break;
+ default : numofbytes = 256; nameParamNo = 0; break;
+ }
+
+ fileNlen = param_getstr(Cmd, nameParamNo, filename);
+
+ if (fileNlen > FILE_PATH_SIZE - 5)
+ fileNlen = FILE_PATH_SIZE - 5;
+
+ // set up buffer
+ uint8_t *data = malloc(numofbytes);
+ if (!data) {
+ PrintAndLog("Fail, cannot allocate memory");
+ return 3;
+ }
+ memset(data, 0, numofbytes);
+
+ // download emulator memory
+ PrintAndLog("Reading emulator memory...");
+ GetEMLFromBigBuf(data, numofbytes, 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");
+
+ // open file
+ if ((f = fopen(filename,"wb")) == NULL) {
+ PrintAndLog("Could not create file name %s", filename);
+ free(data);
+ return 1;
+ }
+ fwrite(data, 1, numofbytes, f);
+ fclose(f);
+ free(data);
+ PrintAndLog("\nSaved %d bytes from emulator memory to file: %s", numofbytes, filename);
+ return 0;
+}
+
+int CmdLegicWipe(const char *Cmd){
+
+ char cmdp = param_getchar(Cmd, 0);
+
+ if ( cmdp == 'h' || cmdp == 'H') return usage_legic_wipe();
+
+ // tagtype
+ legic_card_select_t card;
+ if (legic_get_type(&card)) {
+ PrintAndLog("Failed to identify tagtype");
+ return 1;
+ }
+
+ // set up buffer
+ uint8_t *data = malloc(card.cardsize);
+ if (!data) {
+ PrintAndLog("Fail, cannot allocate memory");
+ return 2;
+ }
+ memset(data, 0, card.cardsize);
+
+ legic_print_type(card.cardsize, 0);
+
+ printf("Erasing");
+
+ // transfer to device
+ size_t len = 0;
+ UsbCommand c = {CMD_WRITER_LEGIC_RF, {0, 0, 0x55}};
+ UsbCommand resp;
+ for(size_t i = 7; i < card.cardsize; i += USB_CMD_DATA_SIZE) {
+
+ printf(".");
+ len = MIN((card.cardsize - 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);
+ return 3;
+ }
+ uint8_t isOK = resp.arg[0] & 0xFF;
+ if ( !isOK ) {
+ PrintAndLog("failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
+ free(data);
+ return 4;
+ }
+ }
+ printf("ok\n");
+ return 0;
+}
+
+int CmdLegicList(const char *Cmd) {
+ CmdHFList("legic");
+ return 0;
+}
+