+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 500))
+ return 2;
+
+ uint8_t isOK = resp.arg[0] & 0xFF;
+ if ( !isOK )
+ return 3;
+
+ memcpy(card, (legic_card_select_t *)resp.d.asBytes, sizeof(legic_card_select_t));
+ return 0;
+}
+void legic_chk_iv(uint32_t *iv){
+ if ( (*iv & 0x7F) != *iv ){
+ *iv &= 0x7F;
+ PrintAndLog("Truncating IV to 7bits, %u", *iv);
+ }
+ // IV must be odd
+ if ( (*iv & 1) == 0 ){
+ *iv |= 0x01;
+ PrintAndLog("LSB of IV must be SET %u", *iv);
+ }
+}
+void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
+ size_t len = 0;
+ UsbCommand c = {CMD_LEGIC_ESET, {0, 0, 0}};
+ for(size_t i = 0; 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, src+i, len);
+ clearCommandBuffer();
+ SendCommand(&c);
+ }
+}
+
+int HFLegicReader(const char *Cmd, bool verbose) {
+
+ char cmdp = param_getchar(Cmd, 0);
+ if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_reader();
+
+ legic_card_select_t card;
+ switch(legic_get_type(&card)){
+ case 1:
+ if ( verbose ) PrintAndLog("command execution time out");
+ return 1;
+ case 2:
+ case 3:
+ if ( verbose ) PrintAndLog("legic card select failed");
+ 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;