From 6016bb7944f1efe600573b614fedc7b8f927c47d Mon Sep 17 00:00:00 2001 From: Michal Demin Date: Thu, 15 Jun 2017 22:09:29 +0200 Subject: [PATCH 1/5] ReaderThreshold is stored in eeprom. Signed-off-by: Michal Demin --- Firmware/Chameleon-Mini/Codec/Codec.c | 1 - Firmware/Chameleon-Mini/Codec/Codec.h | 4 ++-- Firmware/Chameleon-Mini/Settings.c | 3 ++- Firmware/Chameleon-Mini/Settings.h | 1 + Firmware/Chameleon-Mini/Terminal/Commands.c | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Codec/Codec.c b/Firmware/Chameleon-Mini/Codec/Codec.c index bb845e8d..2a23415c 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.c +++ b/Firmware/Chameleon-Mini/Codec/Codec.c @@ -23,7 +23,6 @@ static volatile struct { } ReaderFieldFlags = { false }; uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; -uint16_t ReaderThreshold = 400; // standard value // the following three functions prevent sending data directly after turning on the reader field void CodecReaderFieldStart(void) // DO NOT CALL THIS FUNCTION INSIDE APPLICATION! diff --git a/Firmware/Chameleon-Mini/Codec/Codec.h b/Firmware/Chameleon-Mini/Codec/Codec.h index 4ac44c69..9ee49b04 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.h +++ b/Firmware/Chameleon-Mini/Codec/Codec.h @@ -13,6 +13,7 @@ #include #include "../Common.h" #include "../Configuration.h" +#include "../Settings.h" #include "ISO14443-2A.h" #include "Reader14443-2A.h" @@ -89,7 +90,6 @@ #define CodecPtrRegister1 (*((volatile uint8_t**) &GPIOR8)) #define CodecPtrRegister2 (*((volatile uint8_t**) &GPIORA)) -extern uint16_t ReaderThreshold; extern uint16_t Reader_FWT; #define FWI2FWT(x) ((uint32_t)(256 * 16 * ((uint32_t)1 << (x))) / (CODEC_CARRIER_FREQ / 1000) + 1) @@ -172,7 +172,7 @@ INLINE void CodecInitCommon(void) DACB.CTRLB = DAC_CHSEL_SINGLE_gc; DACB.CTRLC = DAC_REFSEL_AVCC_gc; DACB.CTRLA = DAC_IDOEN_bm | DAC_ENABLE_bm; - DACB.CH0DATA = ReaderThreshold; // real threshold voltage can be calculated with ch0data * Vref / 0xFFF + DACB.CH0DATA = GlobalSettings.ActiveSettingPtr->ReaderThreshold; // real threshold voltage can be calculated with ch0data * Vref / 0xFFF /* Configure Analog Comparator 0 to detect changes in demodulated reader field */ ACA.AC0MUXCTRL = AC_MUXPOS_DAC_gc | AC_MUXNEG_PIN7_gc; diff --git a/Firmware/Chameleon-Mini/Settings.c b/Firmware/Chameleon-Mini/Settings.c index 90cbaf65..1505cc7d 100644 --- a/Firmware/Chameleon-Mini/Settings.c +++ b/Firmware/Chameleon-Mini/Settings.c @@ -25,7 +25,8 @@ SettingsType EEMEM StoredSettings = { .LogMode = DEFAULT_LOG_MODE, .LEDRedFunction = DEFAULT_RED_LED_ACTION, .LEDGreenFunction = DEFAULT_GREEN_LED_ACTION, - .PendingTaskTimeout = DEFAULT_PENDING_TASK_TIMEOUT + .PendingTaskTimeout = DEFAULT_PENDING_TASK_TIMEOUT, + .ReaderThreshold = 400 }} }; diff --git a/Firmware/Chameleon-Mini/Settings.h b/Firmware/Chameleon-Mini/Settings.h index 29e4b9ed..507d9006 100644 --- a/Firmware/Chameleon-Mini/Settings.h +++ b/Firmware/Chameleon-Mini/Settings.h @@ -29,6 +29,7 @@ typedef struct { LEDHookEnum LEDRedFunction; /// Red LED function for this setting. LEDHookEnum LEDGreenFunction; /// Green LED function for this setting. uint16_t PendingTaskTimeout; /// Timeout for timeout commands for this setting, in multiples of 100 ms. + uint16_t ReaderThreshold; } SettingsEntryType; typedef struct { diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c index 84057c63..40331461 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.c +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -578,7 +578,7 @@ CommandStatusIdType CommandSetTimeout(char* OutMessage, const char* InParam) CommandStatusIdType CommandGetThreshold(char* OutParam) { - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ReaderThreshold); + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), GlobalSettings.ActiveSettingPtr->ReaderThreshold); return COMMAND_INFO_OK_WITH_TEXT_ID; } @@ -593,7 +593,7 @@ CommandStatusIdType CommandSetThreshold(char* OutMessage, const char* InParam) if (!sscanf_P(InParam, PSTR("%5d"), &tmp) || tmp > CODEC_MAXIMUM_THRESHOLD) return COMMAND_ERR_INVALID_PARAM_ID; DACB.CH0DATA = tmp; - ReaderThreshold = tmp; + GlobalSettings.ActiveSettingPtr->ReaderThreshold = tmp; return COMMAND_INFO_OK_ID; } From 372fe67da473da47aaab296d7427e0b689ffb787 Mon Sep 17 00:00:00 2001 From: Michal Demin Date: Thu, 15 Jun 2017 22:10:34 +0200 Subject: [PATCH 2/5] Make terminal commands executable from within firmware. Signed-off-by: Michal Demin --- Firmware/Chameleon-Mini/Terminal/CommandLine.c | 12 ++++++++++++ Firmware/Chameleon-Mini/Terminal/CommandLine.h | 1 + 2 files changed, 13 insertions(+) diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/Firmware/Chameleon-Mini/Terminal/CommandLine.c index e62403b6..bd990eed 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.c +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.c @@ -389,6 +389,18 @@ static CommandStatusIdType CallCommandFunc( return Status; } +void CommandExecute(const char* command) +{ + uint8_t i; + + for (i = 0; i < ARRAY_COUNT(CommandTable); i++) { + if (strcmp_P(command, CommandTable[i].Command) == 0) { + CallCommandFunc(&CommandTable[i], CHAR_EXEC_MODE, NULL); + break; + } + } +} + static void DecodeCommand(void) { uint8_t i; diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.h b/Firmware/Chameleon-Mini/Terminal/CommandLine.h index 3ee0388f..097a3ea0 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.h +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.h @@ -15,6 +15,7 @@ void CommandLineInit(void); bool CommandLineProcessByte(uint8_t Byte); void CommandLineTick(void); +void CommandExecute(const char* command); void CommandLineAppendData(void const * const Buffer, uint16_t Bytes); /* Functions for timeout commands */ From c9ebec90f45d1bbf72588fc7cd31b6f72ae64b9e Mon Sep 17 00:00:00 2001 From: Michal Demin Date: Thu, 15 Jun 2017 22:11:17 +0200 Subject: [PATCH 3/5] 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 --- .../Chameleon-Mini/Application/Reader14443A.c | 124 ++++++++++++------ .../Chameleon-Mini/Application/Reader14443A.h | 3 +- .../Chameleon-Mini/Terminal/CommandLine.c | 11 +- Firmware/Chameleon-Mini/Terminal/Commands.c | 14 ++ Firmware/Chameleon-Mini/Terminal/Commands.h | 3 + 5 files changed, 115 insertions(+), 40 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Reader14443A.c b/Firmware/Chameleon-Mini/Application/Reader14443A.c index ab00f003..91434be5 100644 --- a/Firmware/Chameleon-Mini/Application/Reader14443A.c +++ b/Firmware/Chameleon-Mini/Application/Reader14443A.c @@ -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; - - uint8_t i; - for (i = 0; i < CardCandidatesIdx; i++) + if (Reader14443CurrentCommand == Reader14443_Identify) { + if (CardCandidatesIdx == 0) { - if (size <= TERMINAL_BUFFER_SIZE) // prevents buffer overflow + 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++) { - 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; diff --git a/Firmware/Chameleon-Mini/Application/Reader14443A.h b/Firmware/Chameleon-Mini/Application/Reader14443A.h index 63b87061..613beb0f 100644 --- a/Firmware/Chameleon-Mini/Application/Reader14443A.h +++ b/Firmware/Chameleon-Mini/Application/Reader14443A.h @@ -29,7 +29,8 @@ typedef enum { Reader14443_Send_Raw, Reader14443_Get_UID, Reader14443_Read_MF_Ultralight, - Reader14443_Identify + Reader14443_Identify, + Reader14443_Identify_Clone } Reader14443Command; diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/Firmware/Chameleon-Mini/Terminal/CommandLine.c index bd990eed..41a44c9f 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.c +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.c @@ -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) \ diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c index 40331461..83a907b7 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.c +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -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; +} diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.h b/Firmware/Chameleon-Mini/Terminal/Commands.h index 6e2e364f..cb17dcaf 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.h +++ b/Firmware/Chameleon-Mini/Terminal/Commands.h @@ -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 */ From 80ddd96ac5715a8fd4376f376c76a32a0ccb4ea7 Mon Sep 17 00:00:00 2001 From: Michal Demin Date: Thu, 15 Jun 2017 22:11:38 +0200 Subject: [PATCH 4/5] Add CLONE command to button. Signed-off-by: Michal Demin --- Firmware/Chameleon-Mini/Button.c | 7 +++++++ Firmware/Chameleon-Mini/Button.h | 1 + 2 files changed, 8 insertions(+) diff --git a/Firmware/Chameleon-Mini/Button.c b/Firmware/Chameleon-Mini/Button.c index 458db978..e2d2b6ba 100644 --- a/Firmware/Chameleon-Mini/Button.c +++ b/Firmware/Chameleon-Mini/Button.c @@ -4,6 +4,7 @@ #include "Settings.h" #include "Memory.h" #include "Map.h" +#include "Terminal/CommandLine.h" #include "Application/Application.h" #define BUTTON_PORT PORTA @@ -27,6 +28,7 @@ static const MapEntryType PROGMEM ButtonActionMap[] = { { .Id = BUTTON_ACTION_RECALL_MEM, .Text = "RECALL_MEM" }, { .Id = BUTTON_ACTION_TOGGLE_FIELD, .Text = "TOGGLE_FIELD" }, { .Id = BUTTON_ACTION_STORE_LOG, .Text = "STORE_LOG" }, + { .Id = BUTTON_ACTION_CLONE, .Text = "CLONE" }, }; static void ExecuteButtonAction(ButtonActionEnum ButtonAction) @@ -180,6 +182,11 @@ static void ExecuteButtonAction(ButtonActionEnum ButtonAction) break; } + case BUTTON_ACTION_CLONE: + { + CommandExecute("CLONE"); + break; + } default: break; diff --git a/Firmware/Chameleon-Mini/Button.h b/Firmware/Chameleon-Mini/Button.h index 0bc67c97..c23f0138 100644 --- a/Firmware/Chameleon-Mini/Button.h +++ b/Firmware/Chameleon-Mini/Button.h @@ -32,6 +32,7 @@ typedef enum { BUTTON_ACTION_RECALL_MEM, BUTTON_ACTION_TOGGLE_FIELD, BUTTON_ACTION_STORE_LOG, + BUTTON_ACTION_CLONE, /* This has to be last element */ BUTTON_ACTION_COUNT From 62ba2e0ce4e0658368335769236fc964ca6f02ce Mon Sep 17 00:00:00 2001 From: Michal Demin Date: Thu, 24 Aug 2017 19:54:32 +0200 Subject: [PATCH 5/5] fix: clone command was not visible in command list Signed-off-by: Michal Demin --- Firmware/Chameleon-Mini/Terminal/CommandLine.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/Firmware/Chameleon-Mini/Terminal/CommandLine.c index 41a44c9f..a0a6c138 100644 --- a/Firmware/Chameleon-Mini/Terminal/CommandLine.c +++ b/Firmware/Chameleon-Mini/Terminal/CommandLine.c @@ -302,6 +302,13 @@ const PROGMEM CommandEntryType CommandTable[] = { .SetFunc = CommandSetField, .GetFunc = CommandGetField }, + { + .Command = COMMAND_CLONE, + .ExecFunc = CommandExecClone, + .ExecParamFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, { /* This has to be last element */ .Command = COMMAND_LIST_END, .ExecFunc = NO_FUNCTION, @@ -309,13 +316,6 @@ const PROGMEM CommandEntryType CommandTable[] = { .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) \