mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
Add CLONE command
This command is extended original identify command. Upon execution it will do following: - change current config to "reader" mode - identify card - if multiple or no card detected -> end - change config to identified card (mifare classic 1k/4k or ultralight) - set UID of the card Signed-off-by: Michal Demin <michaldemin@gmail.com>
This commit is contained in:
@@ -546,6 +546,7 @@ uint16_t Reader14443AAppProcess(uint8_t* Buffer, uint16_t BitCount)
|
||||
* This function identifies a PICC. *
|
||||
************************************/
|
||||
case Reader14443_Identify:
|
||||
case Reader14443_Identify_Clone:
|
||||
{
|
||||
uint16_t rVal = Reader14443A_Select(Buffer, BitCount);
|
||||
if (Selected)
|
||||
@@ -680,49 +681,98 @@ uint16_t Reader14443AAppProcess(uint8_t* Buffer, uint16_t BitCount)
|
||||
}
|
||||
}
|
||||
|
||||
if (CardCandidatesIdx == 0)
|
||||
{
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, "Unknown card type.");
|
||||
} else if (CardCandidatesIdx == 1) {
|
||||
char tmpType[64];
|
||||
memcpy_P(tmpType, &CardIdentificationList[CardCandidates[0]].Type, 64);
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpType);
|
||||
} else {
|
||||
char tmpBuf[TERMINAL_BUFFER_SIZE];
|
||||
uint16_t size = 0, tmpsize = 0;
|
||||
bool enoughspace = true;
|
||||
if (Reader14443CurrentCommand == Reader14443_Identify) {
|
||||
if (CardCandidatesIdx == 0)
|
||||
{
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, "Unknown card type.");
|
||||
} else if (CardCandidatesIdx == 1) {
|
||||
char tmpType[64];
|
||||
memcpy_P(tmpType, &CardIdentificationList[CardCandidates[0]].Type, 64);
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpType);
|
||||
} else {
|
||||
char tmpBuf[TERMINAL_BUFFER_SIZE];
|
||||
uint16_t size = 0, tmpsize = 0;
|
||||
bool enoughspace = true;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < CardCandidatesIdx; i++)
|
||||
{
|
||||
if (size <= TERMINAL_BUFFER_SIZE) // prevents buffer overflow
|
||||
uint8_t i;
|
||||
for (i = 0; i < CardCandidatesIdx; i++)
|
||||
{
|
||||
char tmpType[64];
|
||||
memcpy_P(tmpType, &CardIdentificationList[CardCandidates[i]].Type, 64);
|
||||
tmpsize = snprintf(tmpBuf + size, TERMINAL_BUFFER_SIZE - size, "%s or ", tmpType);
|
||||
size += tmpsize;
|
||||
} else {
|
||||
break;
|
||||
if (size <= TERMINAL_BUFFER_SIZE) // prevents buffer overflow
|
||||
{
|
||||
char tmpType[64];
|
||||
memcpy_P(tmpType, &CardIdentificationList[CardCandidates[i]].Type, 64);
|
||||
tmpsize = snprintf(tmpBuf + size, TERMINAL_BUFFER_SIZE - size, "%s or ", tmpType);
|
||||
size += tmpsize;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (size > TERMINAL_BUFFER_SIZE)
|
||||
{
|
||||
size -= tmpsize;
|
||||
enoughspace = false;
|
||||
}
|
||||
tmpBuf[size-4] = '.';
|
||||
tmpBuf[size-3] = '\0';
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpBuf);
|
||||
if (!enoughspace)
|
||||
TerminalSendString("There is at least one more card type candidate, but there was not enough terminal buffer space.\r\n");
|
||||
}
|
||||
if (size > TERMINAL_BUFFER_SIZE)
|
||||
{
|
||||
size -= tmpsize;
|
||||
enoughspace = false;
|
||||
// print general data
|
||||
TerminalSendString("ATQA:\t");
|
||||
CommandLineAppendData(&CardCharacteristics.ATQA, 2);
|
||||
TerminalSendString("UID:\t");
|
||||
CommandLineAppendData(CardCharacteristics.UID, CardCharacteristics.UIDSize);
|
||||
TerminalSendString("SAK:\t");
|
||||
CommandLineAppendData(&CardCharacteristics.SAK, 1);
|
||||
} else if (Reader14443CurrentCommand == Reader14443_Identify_Clone) {
|
||||
if (CardCandidatesIdx == 1) {
|
||||
int cfgid = -1;
|
||||
switch (CardCandidates[0]) {
|
||||
case CardType_NXP_MIFARE_Ultralight:
|
||||
{
|
||||
cfgid = CONFIG_MF_ULTRALIGHT;
|
||||
// TODO: enter MFU clone mdoe
|
||||
break;
|
||||
}
|
||||
case CardType_NXP_MIFARE_Classic_1k:
|
||||
case CardType_Infineon_MIFARE_Classic_1k:
|
||||
{
|
||||
if (CardCharacteristics.UIDSize == UIDSize_Single) {
|
||||
cfgid = CONFIG_MF_CLASSIC_1K;
|
||||
} else if (CardCharacteristics.UIDSize == UIDSize_Double) {
|
||||
cfgid = CONFIG_MF_CLASSIC_1K_7B;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CardType_NXP_MIFARE_Classic_4k:
|
||||
case CardType_Nokia_MIFARE_Classic_4k_emulated_6212:
|
||||
case CardType_Nokia_MIFARE_Classic_4k_emulated_6131:
|
||||
{
|
||||
if (CardCharacteristics.UIDSize == UIDSize_Single) {
|
||||
cfgid = CONFIG_MF_CLASSIC_4K;
|
||||
} else if (CardCharacteristics.UIDSize == UIDSize_Double) {
|
||||
cfgid = CONFIG_MF_CLASSIC_4K_7B;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cfgid = -1;
|
||||
}
|
||||
|
||||
if (cfgid > -1) {
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, "Cloned OK!");
|
||||
|
||||
ConfigurationSetById(cfgid);
|
||||
ApplicationReset();
|
||||
ApplicationSetUid(CardCharacteristics.UID);
|
||||
} else {
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, "Clone unsupported!");
|
||||
}
|
||||
} else {
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, "Multiple possibilities, not clonable!");
|
||||
}
|
||||
tmpBuf[size-4] = '.';
|
||||
tmpBuf[size-3] = '\0';
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, tmpBuf);
|
||||
if (!enoughspace)
|
||||
TerminalSendString("There is at least one more card type candidate, but there was not enough terminal buffer space.\r\n");
|
||||
}
|
||||
// print general data
|
||||
TerminalSendString("ATQA:\t");
|
||||
CommandLineAppendData(&CardCharacteristics.ATQA, 2);
|
||||
TerminalSendString("UID:\t");
|
||||
CommandLineAppendData(CardCharacteristics.UID, CardCharacteristics.UIDSize);
|
||||
TerminalSendString("SAK:\t");
|
||||
CommandLineAppendData(&CardCharacteristics.SAK, 1);
|
||||
|
||||
Reader14443CurrentCommand = Reader14443_Do_Nothing;
|
||||
CardCandidatesIdx = 0;
|
||||
|
||||
@@ -29,7 +29,8 @@ typedef enum {
|
||||
Reader14443_Send_Raw,
|
||||
Reader14443_Get_UID,
|
||||
Reader14443_Read_MF_Ultralight,
|
||||
Reader14443_Identify
|
||||
Reader14443_Identify,
|
||||
Reader14443_Identify_Clone
|
||||
} Reader14443Command;
|
||||
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ const PROGMEM CommandEntryType CommandTable[] = {
|
||||
{
|
||||
.Command = COMMAND_FIELD,
|
||||
.ExecFunc = NO_FUNCTION,
|
||||
.ExecParamFunc = NO_FUNCTION,
|
||||
.ExecParamFunc = NO_FUNCTION,
|
||||
.SetFunc = CommandSetField,
|
||||
.GetFunc = CommandGetField
|
||||
},
|
||||
@@ -308,7 +308,14 @@ const PROGMEM CommandEntryType CommandTable[] = {
|
||||
.ExecParamFunc = NO_FUNCTION,
|
||||
.SetFunc = NO_FUNCTION,
|
||||
.GetFunc = NO_FUNCTION
|
||||
}
|
||||
},
|
||||
{
|
||||
.Command = COMMAND_CLONE,
|
||||
.ExecFunc = CommandExecClone,
|
||||
.ExecParamFunc = NO_FUNCTION,
|
||||
.SetFunc = NO_FUNCTION,
|
||||
.GetFunc = NO_FUNCTION
|
||||
}
|
||||
};
|
||||
|
||||
#define STATUS_TABLE_ENTRY(Id, Text) \
|
||||
|
||||
@@ -624,3 +624,17 @@ CommandStatusIdType CommandGetField(char* OutMessage)
|
||||
OutMessage[1] = '\0';
|
||||
return COMMAND_INFO_OK_WITH_TEXT_ID;
|
||||
}
|
||||
|
||||
CommandStatusIdType CommandExecClone(char *OutMessage)
|
||||
{
|
||||
ConfigurationSetById(CONFIG_ISO14443A_READER);
|
||||
|
||||
ApplicationReset();
|
||||
|
||||
Reader14443CurrentCommand = Reader14443_Identify_Clone;
|
||||
Reader14443AAppInit();
|
||||
Reader14443ACodecStart();
|
||||
CommandLinePendingTaskTimeout = &Reader14443AAppTimeout;
|
||||
|
||||
return TIMEOUT_COMMAND;
|
||||
}
|
||||
|
||||
@@ -181,6 +181,9 @@ CommandStatusIdType CommandSetThreshold(char* OutMessage, const char* InParam);
|
||||
CommandStatusIdType CommandSetField(char* OutMessage, const char* InParam);
|
||||
CommandStatusIdType CommandGetField(char* OutMessage);
|
||||
|
||||
#define COMMAND_CLONE "CLONE"
|
||||
CommandStatusIdType CommandExecClone(char* OutMessage);
|
||||
|
||||
#define COMMAND_LIST_END ""
|
||||
/* Defines the end of command list. This is no actual command */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user