diff --git a/Firmware/Chameleon-Mini/Application/Reader14443A.c b/Firmware/Chameleon-Mini/Application/Reader14443A.c index fd1bf83..75e7e11 100644 --- a/Firmware/Chameleon-Mini/Application/Reader14443A.c +++ b/Firmware/Chameleon-Mini/Application/Reader14443A.c @@ -683,6 +683,7 @@ uint16_t Reader14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) { return rVal; } + case Reader14443_Clone_MF_Ultralight: case Reader14443_Read_MF_Ultralight: { static uint8_t MFURead_CurrentAdress = 0; static uint8_t MFUContents[64]; @@ -717,18 +718,28 @@ uint16_t Reader14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) { if (MFURead_CurrentAdress == 16) { Selected = false; MFURead_CurrentAdress = 0; - Reader14443CurrentCommand = Reader14443_Do_Nothing; - char tmpBuf[135]; // 135 = 128 hex digits + 3 * \r\n + \0 - BufferToHexString(tmpBuf, 135, MFUContents, 16); - snprintf(tmpBuf + 32, 135 - 32, "\r\n"); - BufferToHexString(tmpBuf + 32 + 2, 135 - 32 - 2, MFUContents + 16, 16); - snprintf(tmpBuf + 32 + 2 + 32, 135 - 32 - 2 - 32, "\r\n"); - BufferToHexString(tmpBuf + 32 + 2 + 32 + 2, 135 - 32 - 2 - 32 - 2, MFUContents + 32, 16); - snprintf(tmpBuf + 32 + 2 + 32 + 2 + 32, 135 - 32 - 2 - 32 - 2 - 32, "\r\n"); - BufferToHexString(tmpBuf + 32 + 2 + 32 + 2 + 32 + 2, 135 - 32 - 2 - 32 - 2 - 32 - 2, MFUContents + 48, 16); - CodecReaderFieldStop(); - CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpBuf); + if (Reader14443CurrentCommand == Reader14443_Read_MF_Ultralight) { // dump + Reader14443CurrentCommand = Reader14443_Do_Nothing; + char tmpBuf[135]; // 135 = 128 hex digits + 3 * \r\n + \0 + BufferToHexString(tmpBuf, 135, MFUContents, 16); + snprintf(tmpBuf + 32, 135 - 32, "\r\n"); + BufferToHexString(tmpBuf + 32 + 2, 135 - 32 - 2, MFUContents + 16, 16); + snprintf(tmpBuf + 32 + 2 + 32, 135 - 32 - 2 - 32, "\r\n"); + BufferToHexString(tmpBuf + 32 + 2 + 32 + 2, 135 - 32 - 2 - 32 - 2, MFUContents + 32, 16); + snprintf(tmpBuf + 32 + 2 + 32 + 2 + 32, 135 - 32 - 2 - 32 - 2 - 32, "\r\n"); + BufferToHexString(tmpBuf + 32 + 2 + 32 + 2 + 32 + 2, 135 - 32 - 2 - 32 - 2 - 32 - 2, MFUContents + 48, 16); + CodecReaderFieldStop(); + CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpBuf); + } else { // clone + Reader14443CurrentCommand = Reader14443_Do_Nothing; + CodecReaderFieldStop(); + MemoryUploadBlock(&MFUContents, 0, 64); + CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, "Card Cloned to Slot"); + ConfigurationSetById(CONFIG_MF_ULTRALIGHT); + MemoryStore(); + SettingsSave(); + } return 0; } Buffer[0] = 0x30; // MiFare Ultralight read command diff --git a/Firmware/Chameleon-Mini/Application/Reader14443A.h b/Firmware/Chameleon-Mini/Application/Reader14443A.h index 9125470..6a41c93 100644 --- a/Firmware/Chameleon-Mini/Application/Reader14443A.h +++ b/Firmware/Chameleon-Mini/Application/Reader14443A.h @@ -30,7 +30,8 @@ typedef enum { Reader14443_Autocalibrate, Reader14443_Read_MF_Ultralight, Reader14443_Identify, - Reader14443_Identify_Clone + Reader14443_Identify_Clone, + Reader14443_Clone_MF_Ultralight } Reader14443Command; diff --git a/Firmware/Chameleon-Mini/Button.c b/Firmware/Chameleon-Mini/Button.c index 5ce9871..9ebb48f 100644 --- a/Firmware/Chameleon-Mini/Button.c +++ b/Firmware/Chameleon-Mini/Button.c @@ -30,6 +30,7 @@ static const MapEntryType PROGMEM ButtonActionMap[] = { { .Id = BUTTON_ACTION_TOGGLE_FIELD, .Text = "TOGGLE_FIELD" }, { .Id = BUTTON_ACTION_STORE_LOG, .Text = "STORE_LOG" }, { .Id = BUTTON_ACTION_CLONE, .Text = "CLONE" }, + { .Id = BUTTON_ACTION_CLONE_MFU, .Text = "CLONE_MFU" }, }; static void ExecuteButtonAction(ButtonActionEnum ButtonAction) { @@ -178,6 +179,10 @@ static void ExecuteButtonAction(ButtonActionEnum ButtonAction) { CommandExecute("CLONE"); break; } + case BUTTON_ACTION_CLONE_MFU: { + CommandExecute("CLONE_MFU"); + break; + } default: break; diff --git a/Firmware/Chameleon-Mini/Button.h b/Firmware/Chameleon-Mini/Button.h index c84f603..bd5172a 100644 --- a/Firmware/Chameleon-Mini/Button.h +++ b/Firmware/Chameleon-Mini/Button.h @@ -33,6 +33,7 @@ typedef enum { BUTTON_ACTION_TOGGLE_FIELD, BUTTON_ACTION_STORE_LOG, BUTTON_ACTION_CLONE, + BUTTON_ACTION_CLONE_MFU, /* This has to be last element */ BUTTON_ACTION_COUNT diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/Firmware/Chameleon-Mini/Terminal/CommandLine.c index 3982332..ce83b14 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.c +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.c @@ -274,6 +274,13 @@ const PROGMEM CommandEntryType CommandTable[] = { .SetFunc = NO_FUNCTION, .GetFunc = NO_FUNCTION }, + { + .Command = COMMAND_CLONE_MFU, + .ExecFunc = CommandExecCloneMFU, + .ExecParamFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, { .Command = COMMAND_IDENTIFY_CARD, .ExecFunc = CommandExecIdentifyCard, diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c index 8583d07..4665869 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.c +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -488,6 +488,17 @@ CommandStatusIdType CommandExecDumpMFU(char *OutMessage) { return TIMEOUT_COMMAND; } +CommandStatusIdType CommandExecCloneMFU(char *OutMessage) { + ConfigurationSetById(CONFIG_ISO14443A_READER); + ApplicationReset(); + + Reader14443CurrentCommand = Reader14443_Clone_MF_Ultralight; + Reader14443AAppInit(); + Reader14443ACodecStart(); + CommandLinePendingTaskTimeout = &Reader14443AAppTimeout; + return TIMEOUT_COMMAND; +} + CommandStatusIdType CommandExecGetUid(char *OutMessage) { // this function is for reading the uid in reader mode if (GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER) return COMMAND_ERR_INVALID_USAGE_ID; diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.h b/Firmware/Chameleon-Mini/Terminal/Commands.h index 93e08e0..60b62ca 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.h +++ b/Firmware/Chameleon-Mini/Terminal/Commands.h @@ -166,6 +166,9 @@ CommandStatusIdType CommandExecGetUid(char *OutMessage); #define COMMAND_DUMP_MFU "DUMP_MFU" CommandStatusIdType CommandExecDumpMFU(char *OutMessage); +#define COMMAND_CLONE_MFU "CLONE_MFU" +CommandStatusIdType CommandExecCloneMFU(char *OutMessage); + #define COMMAND_IDENTIFY_CARD "IDENTIFY" CommandStatusIdType CommandExecIdentifyCard(char *OutMessage);