diff --git a/Firmware/ChameleonMini/AntennaLevel.c b/Firmware/ChameleonMini/AntennaLevel.c
index 9ce6c60..cabdd17 100644
--- a/Firmware/ChameleonMini/AntennaLevel.c
+++ b/Firmware/ChameleonMini/AntennaLevel.c
@@ -1,18 +1,32 @@
#include "AntennaLevel.h"
#include "Application/Application.h"
-#define FIELD_MIN_RSSI 500
+void AntennaLevelInit(void) {
+ ADCA.CTRLA = ADC_ENABLE_bm;
+ ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;
+ ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm;
+ ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc;
+ ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
+ ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc;
+}
+
+uint16_t AntennaLevelGet(void) {
+ ADCA.CH0.CTRL |= ADC_CH_START_bm;
+ while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) );
+
+ ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm;
+
+ int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET;
+ if (Result < 0) Result = 0;
+
+ return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR);
+}
-void AntennaLevelTick(void)
-{
+void AntennaLevelTick(void) {
uint16_t rssi = AntennaLevelGet();
- if (rssi < FIELD_MIN_RSSI)
- {
- //LEDHook(LED_FIELD_DETECTED, LED_OFF);
- if (ActiveConfiguration.UidSize != 0) // this implies that we are emulating right now
- ApplicationReset(); // reset the application just like a real card gets reset when there is no field
- } else {
- //LEDHook(LED_FIELD_DETECTED, LED_ON);
+ // UidSize != 0 implies that we are emulating right now
+ if( (rssi < ANTENNA_FIELD_MIN_RSSI) && (ActiveConfiguration.UidSize != 0) ) {
+ ApplicationReset(); // reset the application just like a real card gets reset when there is no field
}
}
diff --git a/Firmware/ChameleonMini/AntennaLevel.h b/Firmware/ChameleonMini/AntennaLevel.h
index 806120d..b89ab3d 100644
--- a/Firmware/ChameleonMini/AntennaLevel.h
+++ b/Firmware/ChameleonMini/AntennaLevel.h
@@ -58,40 +58,22 @@
#include "Common.h"
-#define ANTENNA_LEVEL_R1 10E3
-#define ANTENNA_LEVEL_R2 220E0
-#define ANTENNA_LEVEL_VREF 1.0
-#define ANTENNA_LEVEL_RES 4096
-#define ANTENNA_LEVEL_OFFSET 190 /* LSB */
+#define ANTENNA_LEVEL_R1 10E3
+#define ANTENNA_LEVEL_R2 220E0
+#define ANTENNA_LEVEL_VREF 1.0
+#define ANTENNA_LEVEL_RES 4096
+#define ANTENNA_LEVEL_OFFSET 190 /* LSB */
-#define ANTENNA_LEVEL_MILLIVOLT 1E3
-#define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) )
-#define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16)
-#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5))
-#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE)
+#define ANTENNA_LEVEL_MILLIVOLT 1E3
+#define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) )
+#define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16)
+#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5))
+#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE)
-static inline void AntennaLevelInit(void)
-{
- ADCA.CTRLA = ADC_ENABLE_bm;
- ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;
- ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm;
- ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc;
- ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
- ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc;
+#define ANTENNA_FIELD_MIN_RSSI 500
-}
-
-static inline uint16_t AntennaLevelGet(void)
-{
- ADCA.CH0.CTRL |= ADC_CH_START_bm;
- while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) );
-
- ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm;
-
- int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET;
- if (Result < 0) Result = 0;
-
- return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR);
-}
+void AntennaLevelInit(void);
+uint16_t AntennaLevelGet(void);
+void AntennaLevelTick(void);
#endif /* ANTENNALEVEL_H_ */
diff --git a/Firmware/ChameleonMini/Application/Application.h b/Firmware/ChameleonMini/Application/Application.h
index aca50f0..7f9a8a5 100644
--- a/Firmware/ChameleonMini/Application/Application.h
+++ b/Firmware/ChameleonMini/Application/Application.h
@@ -28,6 +28,10 @@ INLINE void ApplicationTick(void) {
ActiveConfiguration.ApplicationTickFunc();
}
+INLINE void ApplicationButton(void) {
+ ActiveConfiguration.ApplicationButtonFunc();
+}
+
INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) {
return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount);
}
diff --git a/Firmware/ChameleonMini/Application/MifareClassic.c b/Firmware/ChameleonMini/Application/MifareClassic.c
index 6b0884c..8eed342 100644
--- a/Firmware/ChameleonMini/Application/MifareClassic.c
+++ b/Firmware/ChameleonMini/Application/MifareClassic.c
@@ -7,12 +7,19 @@
*
*/
+#if defined(CONFIG_MF_CLASSIC_SUPPORT) || defined(CONFIG_MF_CLASSIC_DETECTION_SUPPORT) \
+ || defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT) || defined(SUPPORT_MF_CLASSIC_MAGIC_MODE) \
+ || defined(CONFIG_MF_CLASSIC_LOG_SUPPORT)
+
#include "MifareClassic.h"
#include "ISO14443-3A.h"
#include "Crypto1.h"
#include "../Random.h"
#include "../Codec/ISO14443-2A.h"
#include "../Memory/Memory.h"
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+#include "System.h"
+#endif
/* TODO: Access control not implemented yet
// Decoding table for Access conditions of a data block
@@ -171,15 +178,27 @@ static bool is7BytesUID = false;
static bool isFromHaltChain = false;
/* To check if previous step of any cascading sequence has passed */
static bool isCascadeStepOnePassed = false;
-/* To enable MF_DETECTION behavior */
+/* To enable MF_CLASSIC_DETECTION behavior */
static bool isDetectionEnabled = false;
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
static bool isDetectionCanaryWritten = false;
static uint8_t DetectionCanary[DETECTION_BLOCK0_CANARY_SIZE] = { DETECTION_BLOCK0_CANARY };
static uint8_t DetectionDataSave[DETECTION_BYTES_PER_SAVE] = {0};
static uint8_t DetectionAttemptsKeyA = 0;
static uint8_t DetectionAttemptsKeyB = 0;
#endif
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+static bool isBruteEnabled = false;
+static uint8_t BruteIdleRounds = 0;
+static uint32_t BruteCurrentUid = 0;
+#endif
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+static bool isLogEnabled = false;
+static uint32_t LogBytesWrote = 0;
+static uint16_t LogBytesBuffered = 0;
+static uint32_t LogMaxBytes = 0;
+static uint8_t LogLineBuffer[MFCLASSIC_LOG_MEM_LINE_BUFFER_LEN] = { 0 };
+#endif
/* TODO: Access control not implemented yet
* Decode Access conditions for a block
@@ -275,6 +294,31 @@ INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) {
Block[11] = Block[3];
}
+#if defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT) || defined(CONFIG_MF_CLASSIC_LOG_SUPPORT)
+uint32_t BytesToUint32(uint8_t * Buffer) {
+ return ( (((uint32_t)(Buffer[0])) << 24)
+ | (((uint32_t)(Buffer[1])) << 16)
+ | (((uint32_t)(Buffer[2])) << 8)
+ | ((uint32_t)(Buffer[3])) );
+}
+
+uint16_t BytesToUint16(uint8_t * Buffer) {
+ return ( (((uint16_t)(Buffer[0])) << 8) | ((uint16_t)(Buffer[1])) );
+}
+
+void Uint32ToBytes(uint32_t Uint32, uint8_t * Buffer) {
+ Buffer[0] = ((uint8_t)(Uint32 >> 24) & 0xFF);
+ Buffer[1] = ((uint8_t)(Uint32 >> 16) & 0xFF);
+ Buffer[2] = ((uint8_t)(Uint32 >> 8) & 0xFF);
+ Buffer[3] = ((uint8_t)(Uint32 & 0xFF));
+}
+
+void Uint16ToBytes(uint16_t Uint16, uint8_t * Buffer) {
+ Buffer[0] = ((uint8_t)(Uint16 >> 8) & 0xFF);
+ Buffer[1] = ((uint8_t)(Uint16 & 0xFF));
+}
+#endif
+
void MifareClassicAppInit(uint16_t ATQA_4B, uint8_t SAK, bool is7B) {
State = STATE_IDLE;
is7BytesUID = is7B;
@@ -294,13 +338,11 @@ void MifareClassicAppInit4K(void) {
(ActiveConfiguration.UidSize == MFCLASSIC_UID_7B_SIZE) );
}
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
void MifareClassicAppInitMini(void) {
MifareClassicAppInit(MFCLASSIC_MINI_ATQA_VALUE, MFCLASSIC_MINI_SAK_VALUE, false);
}
-#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
void MifareClassicAppDetectionInit(void) {
isDetectionEnabled = true;
DetectionAttemptsKeyA = 0;
@@ -309,14 +351,161 @@ void MifareClassicAppDetectionInit(void) {
}
#endif
-void MifareClassicAppReset(void) {
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+void MifareClassicAppBruteGetCurrentUid(void) {
+ uint8_t TempUid[MFCLASSIC_UID_SIZE];
+ MifareClassicGetUid(TempUid);
+ BruteCurrentUid = BytesToUint32(TempUid);
+}
+
+void MifareClassicAppBruteWrite(void) {
+ uint8_t bruteStatusByte = (isBruteEnabled) ? (BRUTE_MEM_BRUTED_STATUS_CANARY) : (BRUTE_MEM_BRUTED_STATUS_RESET);
+ AppWorkingMemoryWrite(&bruteStatusByte, BRUTE_MEM_BRUTED_STATUS_ADDR, BRUTE_MEM_BRUTED_STATUS_SIZE);
+ uint8_t TempUid[MFCLASSIC_UID_SIZE];
+ Uint32ToBytes(BruteCurrentUid, TempUid);
+ MifareClassicSetUid(TempUid);
+}
+
+void MifareClassicAppBruteInit(void) {
+ MifareClassicAppInit(MFCLASSIC_1K_ATQA_VALUE, MFCLASSIC_1K_SAK_VALUE, false);
+ uint8_t bruteStatusByte = BRUTE_MEM_BRUTED_STATUS_CANARY;
+ AppWorkingMemoryRead(&bruteStatusByte, BRUTE_MEM_BRUTED_STATUS_ADDR, BRUTE_MEM_BRUTED_STATUS_SIZE);
+ isBruteEnabled = (bruteStatusByte == BRUTE_MEM_BRUTED_STATUS_CANARY);
+ BruteIdleRounds = 0;
+ MifareClassicAppBruteGetCurrentUid();
+}
+
+void MifareClassicAppBruteStop(void) {
+ isBruteEnabled = false;
+ BruteIdleRounds = 0;
+ MifareClassicAppBruteWrite();
+}
+
+void MifareClassicAppBruteMove(void) {
+ isBruteEnabled = true;
+ BruteIdleRounds = 0;
+ BruteCurrentUid++;
State = STATE_IDLE;
+ MifareClassicAppBruteWrite();
}
-void MifareClassicAppTask(void) {
+void MifareClassicAppBruteToggle(void) {
+ if(isBruteEnabled) {
+ MifareClassicAppBruteStop();
+ } else {
+ MifareClassicAppBruteGetCurrentUid();
+ MifareClassicAppBruteMove();
+ }
+}
+void MifareClassicAppBruteTick(void) {
+ // If we were using same UID for too long, change it
+ if( isBruteEnabled ) {
+ if( BruteIdleRounds >= BRUTE_IDLE_MAX_ROUNDS ) {
+ MifareClassicAppBruteMove();
+ } else {
+ BruteIdleRounds++;
+ }
+ }
}
+#endif
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+void MifareClassicAppLogCheck(void) {
+ uint8_t headerLine[MFCLASSIC_LOG_MEM_LOG_HEADER_LEN];
+ AppWorkingMemoryRead(&headerLine, MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR, MFCLASSIC_LOG_MEM_LOG_HEADER_LEN);
+ if( (headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] == MFCLASSIC_LOG_MEM_STATUS_CANARY)
+ || (headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] == MFCLASSIC_LOG_MEM_STATUS_RESET) ) {
+ isLogEnabled = (headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] == MFCLASSIC_LOG_MEM_STATUS_CANARY);
+ LogBytesWrote = BytesToUint32(&headerLine[MFCLASSIC_LOG_MEM_WROTEBYTES_ADDR]);
+ } else {
+ isLogEnabled = true;
+ LogBytesWrote = 0;
+ }
+}
+
+void MifareClassicAppLogWriteHeader(void) {
+ uint8_t headerLine[MFCLASSIC_LOG_MEM_LOG_HEADER_LEN] = { 0 };
+ headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] = (isLogEnabled) ? (MFCLASSIC_LOG_MEM_STATUS_CANARY) : (MFCLASSIC_LOG_MEM_STATUS_RESET);
+ Uint32ToBytes(LogBytesWrote, &headerLine[MFCLASSIC_LOG_MEM_WROTEBYTES_ADDR]);
+ AppWorkingMemoryWrite(headerLine, MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR, MFCLASSIC_LOG_MEM_LOG_HEADER_LEN);
+}
+
+void MifareClassicAppLogBufferLine(const uint8_t * Data, uint16_t BitCount, uint8_t Source) {
+ uint16_t timeNow = SystemGetSysTick();
+ uint16_t dataBytesToBuffer = (BitCount / BITS_PER_BYTE);
+ if( !(BitCount % BITS_PER_BYTE) ) dataBytesToBuffer++;
+ if( (LogBytesBuffered + MFCLASSIC_LOG_LINE_OVERHEAD) < MFCLASSIC_LOG_MEM_LINE_BUFFER_LEN) {
+ uint16_t idx = LogBytesBuffered+MFCLASSIC_LOG_MEM_LINE_START_ADDR;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_LINE_START;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ Uint16ToBytes(timeNow, &LogLineBuffer[idx]);
+ idx += MFCLASSIC_LOG_MEM_LINE_TIMESTAMP_LEN;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_SEPARATOR;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = Source;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_SEPARATOR;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = State;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_SEPARATOR;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ memcpy(&LogLineBuffer[idx], Data, dataBytesToBuffer);
+ idx += dataBytesToBuffer;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_LINE_END;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_EOL_CR;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_EOL_LF;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogLineBuffer[idx] = MFCLASSIC_LOG_EOS;
+ idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
+ LogBytesBuffered = idx;
+ }
+}
+
+void MifareClassicAppLogWriteLines(void) {
+ if( isLogEnabled && (LogBytesBuffered > 0) ) {
+ if( (LogBytesWrote + LogBytesBuffered) >= LogMaxBytes) {
+ LogBytesWrote = 0;
+ }
+ AppWorkingMemoryWrite(LogLineBuffer, MFCLASSIC_LOG_MEM_LOG_HEADER_LEN+LogBytesWrote, LogBytesBuffered);
+ LogBytesWrote += LogBytesBuffered;
+ LogBytesBuffered = 0;
+ MifareClassicAppLogWriteHeader();
+ }
+}
+
+void MifareClassicAppLogStop(void) {
+ isLogEnabled = false;
+ MifareClassicAppLogWriteHeader();
+}
+
+void MifareClassicAppLogStart(void) {
+ isLogEnabled = true;
+ MifareClassicAppLogWriteHeader();
+}
+
+void MifareClassicAppLogInit(void) {
+ MifareClassicAppInit(MFCLASSIC_1K_ATQA_VALUE, MFCLASSIC_1K_SAK_VALUE, false);
+ MifareClassicAppLogCheck();
+ LogMaxBytes = ( AppWorkingMemorySize() - MFCLASSIC_LOG_MEM_LOG_HEADER_LEN );
+ LogBytesBuffered = 0;
+}
+
+void MifareClassicAppLogToggle(void) {
+ if(isLogEnabled) {
+ MifareClassicAppLogStop();
+ } else {
+ MifareClassicAppLogStart();
+ }
+}
+#endif
+
+void MifareClassicAppReset(void) {
+ State = STATE_IDLE;
+}
/* Handle a MFCLASSIC_CMD_HALT during main process, as can be raised in many states.
* Sets State, response buffer and response size. Returns if valid HALT. */
@@ -374,7 +563,7 @@ void mfcHandleAuthenticationRequest(bool isNested, uint8_t * Buffer, uint16_t *
uint16_t KeyAddress;
/* Save Nonce in detection mode */
if(isDetectionEnabled && !isNested) {
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
memset(DetectionDataSave, 0x00, DETECTION_BYTES_PER_SAVE);
// Save reader's auth phase 1: KEY type (A or B), and sector number
memcpy(DetectionDataSave, Buffer, DETECTION_READER_AUTH_P1_SIZE);
@@ -392,12 +581,12 @@ void mfcHandleAuthenticationRequest(bool isNested, uint8_t * Buffer, uint16_t *
}
KeyAddress = (uint16_t) SectorAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK + KeyOffset;
}
- AppMemoryRead(Key, KeyAddress, MFCLASSIC_MEM_KEY_SIZE);
+ AppCardMemoryRead(Key, KeyAddress, MFCLASSIC_MEM_KEY_SIZE);
/* Load UID */
if (is7BytesUID) {
- AppMemoryRead(Uid, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE);
+ AppCardMemoryRead(Uid, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE);
} else {
- AppMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE);
+ AppCardMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE);
}
/* Proceed with nested or regular authent */
if(isNested) {
@@ -420,7 +609,7 @@ void mfcHandleAuthenticationRequest(bool isNested, uint8_t * Buffer, uint16_t *
uint8_t CardNonce[MFCLASSIC_MEM_NONCE_SIZE] = {0x01, 0x20, 0x01, 0x45};
uint8_t CardNonceSuccessor1[MFCLASSIC_MEM_NONCE_SIZE] = {0x63, 0xe5, 0xbc, 0xa7};
uint8_t CardNonceSuccessor2[MFCLASSIC_MEM_NONCE_SIZE] = {0x99, 0x37, 0x30, 0xbd};
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
if(isDetectionEnabled) {
// Save sent 'random' nonce
memcpy(DetectionDataSave+DETECTION_READER_AUTH_P1_SIZE, CardNonce, MFCLASSIC_MEM_NONCE_SIZE);
@@ -457,6 +646,12 @@ void mfcEncryptBuffer(uint8_t * Output, uint8_t * Input, uint8_t Size) {
}
uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+ /* Log what comes from reader if logging enabled */
+ if(isLogEnabled) {
+ MifareClassicAppLogBufferLine(Buffer, BitCount, MFCLASSIC_LOG_READER);
+ }
+#endif
/* Size of data (byte) we will send back to reader. Is main process return value */
uint16_t retSize = ISO14443A_APP_NO_RESPONSE;
/* WUPA/REQA and HALT may occur in every state. We handle is first, so we can skip
@@ -494,7 +689,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
retSize = MFCLASSIC_ACK_NAK_FRAME_SIZE;
} else if (Buffer[0] == MFCLASSIC_CMD_READ) {
/* Read command. Read data from memory and append CRCA. */
- AppMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
ISO14443AAppendCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK);
retSize = (MFCLASSIC_CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE)
* BITS_PER_BYTE;
@@ -515,7 +710,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
if (ISO14443ACheckCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK)) {
/* CRC check passed. Write data into memory and send ACK. */
if (!ActiveConfiguration.ReadOnly) {
- AppMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
}
Buffer[0] = MFCLASSIC_ACK_VALUE;
} else {
@@ -549,7 +744,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
SAK = CardSAKValue;
NextState = STATE_ACTIVE;
}
- AppMemoryRead(UidCLReadBuffer, UidMemAddr, UidReadSize);
+ AppCardMemoryRead(UidCLReadBuffer, UidMemAddr, UidReadSize);
if (ISO14443ASelect(Buffer, &BitCount, UidCL, SAK)) {
/* TODO: Access control not implemented yet
* AccessAddress = MFCLASSIC_MEM_INVALID_ADDRESS; // invalid, force reload */
@@ -563,7 +758,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
/* 'Sequence 1' as per MF1S50YYX_V1, title 10.1.2 */
if ( is7BytesUID && (Buffer[0] == ISO14443A_CMD_SELECT_CL2) ) {
uint8_t UidCL[ISO14443A_CL_UID_SIZE];
- AppMemoryRead(UidCL, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE);
+ AppCardMemoryRead(UidCL, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE);
if (ISO14443ASelect(Buffer, &BitCount, UidCL, CardSAKValue)) {
State = STATE_ACTIVE;
isCascadeStepOnePassed = false;
@@ -572,7 +767,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
/* 'Sequence 2' as per MF1S50YYX_V1, title 10.1.2 */
} else if (Buffer[0] == MFCLASSIC_CMD_READ) {
/* Read sector 0 / block 0 and send in plain */
- AppMemoryRead(Buffer, MFCLASSIC_MEM_S0B0_ADDRESS, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryRead(Buffer, MFCLASSIC_MEM_S0B0_ADDRESS, MFCLASSIC_MEM_BYTES_PER_BLOCK);
ISO14443AAppendCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK);
State = STATE_ACTIVE;
isCascadeStepOnePassed = false;
@@ -605,7 +800,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
case STATE_AUTHING:
if(isDetectionEnabled) {
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
// Save reader's auth phase 2 answer to our nonce from STATE_ACTIVE
memcpy(DetectionDataSave+DETECTION_SAVE_P2_OFFSET, Buffer, DETECTION_READER_AUTH_P2_SIZE);
// Align data storage in each KEYX dedicated memory space, and iterate counters
@@ -621,10 +816,10 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
}
// Write to app memory
if(!isDetectionCanaryWritten) {
- AppMemoryWrite(DetectionCanary, DETECTION_BLOCK0_CANARY_ADDR, DETECTION_BLOCK0_CANARY_SIZE);
+ AppWorkingMemoryWrite(DetectionCanary, DETECTION_BLOCK0_CANARY_ADDR, DETECTION_BLOCK0_CANARY_SIZE);
isDetectionCanaryWritten = true;
}
- AppMemoryWrite(DetectionDataSave, memSaveAddr, DETECTION_BYTES_PER_SAVE);
+ AppWorkingMemoryWrite(DetectionDataSave, memSaveAddr, DETECTION_BYTES_PER_SAVE);
State = STATE_ACTIVE;
#endif
} else {
@@ -662,7 +857,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
} else {
if (Buffer[0] == MFCLASSIC_CMD_READ) {
/* Read command. Read data from memory and append CRCA. */
- AppMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
ISO14443AAppendCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK);
/* Encrypt and calculate parity bits. */
mfcEncryptBuffer(Buffer, Buffer, (ISO14443A_CRCA_SIZE + MFCLASSIC_MEM_BYTES_PER_BLOCK));
@@ -683,7 +878,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
} else if (Buffer[0] == MFCLASSIC_CMD_TRANSFER) {
/* Write back the global block buffer to the desired block address */
if (!ActiveConfiguration.ReadOnly) {
- AppMemoryWrite(BlockBuffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryWrite(BlockBuffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
} else {
/* In read only mode, silently ignore the write */
}
@@ -728,7 +923,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
if (ISO14443ACheckCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK)) {
/* Silently ignore in ReadOnly mode */
if (!ActiveConfiguration.ReadOnly) {
- AppMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
}
Buffer[0] = MFCLASSIC_ACK_VALUE ^ Crypto1Nibble();
} else {
@@ -752,7 +947,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
/* We could also get an encrypted HALT... */
if ( !mfcHandleHaltCommand(Buffer, &retSize) ) {
if (ISO14443ACheckCRCA(Buffer, MFCLASSIC_MEM_VALUE_SIZE)) {
- AppMemoryRead(BlockBuffer, (uint16_t) CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
+ AppCardMemoryRead(BlockBuffer, (uint16_t) CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK);
if (CheckValueIntegrity(BlockBuffer)) {
uint32_t ParamValue;
uint32_t BlockValue;
@@ -787,26 +982,31 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
State = isFromHaltChain ? STATE_HALT : STATE_IDLE;
} /* End of states switch/case */
} /* End of if/else WUPA/REQA condition */
-
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+ /* Log what goes from tag if logging enabled */
+ if(isLogEnabled) {
+ MifareClassicAppLogBufferLine(Buffer, retSize, MFCLASSIC_LOG_TAG);
+ }
+#endif
return retSize;
}
void MifareClassicGetUid(ConfigurationUidType Uid) {
if (is7BytesUID) {
- AppMemoryRead(&Uid[0], MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE-1);
- AppMemoryRead(&Uid[3], MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE);
+ AppCardMemoryRead(&Uid[0], MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE-1);
+ AppCardMemoryRead(&Uid[3], MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE);
} else {
- AppMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE);
+ AppCardMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE);
}
}
void MifareClassicSetUid(ConfigurationUidType Uid) {
if (is7BytesUID) {
- AppMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize);
+ AppCardMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize);
} else {
uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3];
- AppMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE);
- AppMemoryWrite(&BCC, MFCLASSIC_MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
+ AppCardMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE);
+ AppCardMemoryWrite(&BCC, MFCLASSIC_MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
}
}
@@ -825,3 +1025,5 @@ void MifareClassicGetSak(uint8_t * Sak) {
void MifareClassicSetSak(uint8_t Sak) {
CardSAKValue = Sak;
}
+
+#endif /* Compilation support */
diff --git a/Firmware/ChameleonMini/Application/MifareClassic.h b/Firmware/ChameleonMini/Application/MifareClassic.h
index aa7de38..b2136b5 100644
--- a/Firmware/ChameleonMini/Application/MifareClassic.h
+++ b/Firmware/ChameleonMini/Application/MifareClassic.h
@@ -7,6 +7,10 @@
*
*/
+#if defined(CONFIG_MF_CLASSIC_SUPPORT) || defined(CONFIG_MF_CLASSIC_DETECTION_SUPPORT) \
+ || defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT) || defined(SUPPORT_MF_CLASSIC_MAGIC_MODE) \
+ || defined(CONFIG_MF_CLASSIC_LOG_SUPPORT)
+
#ifndef MIFARECLASSIC_H_
#define MIFARECLASSIC_H_
@@ -17,9 +21,7 @@
#define MFCLASSIC_UID_7B_SIZE ISO14443A_UID_SIZE_DOUBLE
#define MFCLASSIC_1K_MEM_SIZE 1024
#define MFCLASSIC_4K_MEM_SIZE 4096
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
#define MFCLASSIC_MINI_MEM_SIZE 320
-#endif
#define MFCLASSIC_1K_ATQA_VALUE 0x0004
#define MFCLASSIC_1K_7B_ATQA_VALUE 0x0044
@@ -28,10 +30,8 @@
#define MFCLASSIC_7B_ATQA_MASK 0x40
#define MFCLASSIC_1K_SAK_VALUE 0x08
#define MFCLASSIC_4K_SAK_VALUE 0x18
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
#define MFCLASSIC_MINI_ATQA_VALUE MFCLASSIC_1K_ATQA_VALUE
#define MFCLASSIC_MINI_SAK_VALUE 0x09
-#endif
#define MFCLASSIC_SAK_CL1_VALUE ISO14443A_SAK_INCOMPLETE
#define MFCLASSIC_MEM_S0B0_ADDRESS 0x00
@@ -156,7 +156,7 @@ C1 C2 C3 read write increment decrement,
#define MFCLASSIC_ACC_BLOCK_DECREMENT 0x08
*/
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
#define DETECTION_BYTES_PER_SAVE 16
#define DETECTION_READER_AUTH_P1_SIZE 4
#define DETECTION_READER_AUTH_P2_SIZE 8
@@ -177,10 +177,45 @@ C1 C2 C3 read write increment decrement,
#define DETECTION_BLOCK0_CANARY_SIZE 8
#endif
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+#define BRUTE_MEM_BRUTED_UID_ADDR 8
+#define BRUTE_MEM_BRUTED_STATUS_CANARY 0xB1
+#define BRUTE_MEM_BRUTED_STATUS_RESET 0xB0
+#define BRUTE_MEM_BRUTED_STATUS_ADDR 0
+#define BRUTE_MEM_BRUTED_STATUS_SIZE 1
+#define BRUTE_WORKING_MEM_SIZE 16
+#define BRUTE_IDLE_MAX_ROUNDS 3
+#endif
+
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+#define MFCLASSIC_LOG_LINE_START 0x3E
+#define MFCLASSIC_LOG_LINE_END 0x3B
+#define MFCLASSIC_LOG_EOL_CR 0x0D
+#define MFCLASSIC_LOG_EOL_LF 0x0A
+#define MFCLASSIC_LOG_EOS 0x00
+#define MFCLASSIC_LOG_SEPARATOR 0x21
+#define MFCLASSIC_LOG_READER 0x52
+#define MFCLASSIC_LOG_TAG 0x54
+#define MFCLASSIC_LOG_MEM_CHAR_LEN 1
+#define MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR
+#define MFCLASSIC_LOG_MEM_STATUS_CANARY 0x71
+#define MFCLASSIC_LOG_MEM_STATUS_RESET 0x70
+#define MFCLASSIC_LOG_MEM_STATUS_LEN 1
+#define MFCLASSIC_LOG_MEM_WROTEBYTES_ADDR 12
+#define MFCLASSIC_LOG_MEM_WROTEBYTES_LEN sizeof(uint32_t)
+#define MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR 0
+#define MFCLASSIC_LOG_MEM_LOG_HEADER_LEN 16
+#define MFCLASSIC_LOG_MEM_LINE_BUFFER_LEN 128
+#define MFCLASSIC_LOG_MEM_LINE_START_ADDR 0
+#define MFCLASSIC_LOG_MEM_LINE_TIMESTAMP_LEN sizeof(uint16_t)
+#define MFCLASSIC_LOG_LINE_OVERHEAD (MFCLASSIC_LOG_MEM_LINE_TIMESTAMP_LEN+MFCLASSIC_LOG_MEM_CHAR_LEN*10)
+#define MFCLASSIC_LOG_BUFFER_OVERFLOW 0x0F
+#endif
+
void MifareClassicAppInit1K(void);
void MifareClassicAppInit4K(void);
+void MifareClassicAppInitMini(void);
void MifareClassicAppReset(void);
-void MifareClassicAppTask(void);
uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount);
@@ -193,12 +228,22 @@ void MifareClassicSetAtqa(uint16_t Atqa);
void MifareClassicGetSak(uint8_t * Sak);
void MifareClassicSetSak(uint8_t Sak);
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
-void MifareClassicAppInitMini(void);
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
+void MifareClassicAppDetectionInit(void);
#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
-void MifareClassicAppDetectionInit(void);
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+void MifareClassicAppBruteInit(void);
+void MifareClassicAppBruteTick(void);
+void MifareClassicAppBruteToggle(void);
+#endif
+
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+void MifareClassicAppLogInit(void);
+void MifareClassicAppLogWriteLines(void);
+void MifareClassicAppLogToggle(void);
#endif
#endif /* MIFARECLASSIC_H_ */
+
+#endif /* Compilation support */
diff --git a/Firmware/ChameleonMini/Application/MifareUltralight.c b/Firmware/ChameleonMini/Application/MifareUltralight.c
index ec0ca52..6d09ddd 100644
--- a/Firmware/ChameleonMini/Application/MifareUltralight.c
+++ b/Firmware/ChameleonMini/Application/MifareUltralight.c
@@ -5,6 +5,8 @@
* Author: skuser
*/
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+
#include "MifareUltralight.h"
#include "ISO14443-3A.h"
#include "../Codec/ISO14443-2A.h"
@@ -140,8 +142,8 @@ static void AppInitEV1Common(void)
/* Set up the emulation flavor */
Flavor = UL_EV1;
/* Fetch some of the configuration into RAM */
- AppMemoryRead(&FirstAuthenticatedPage, ConfigAreaAddress + CONF_AUTH0_OFFSET, 1);
- AppMemoryRead(&Access, ConfigAreaAddress + CONF_ACCESS_OFFSET, 1);
+ AppCardMemoryRead(&FirstAuthenticatedPage, ConfigAreaAddress + CONF_AUTH0_OFFSET, 1);
+ AppCardMemoryRead(&Access, ConfigAreaAddress + CONF_ACCESS_OFFSET, 1);
ReadAccessProtected = !!(Access & CONF_ACCESS_PROT);
AppInitCommon();
}
@@ -163,11 +165,6 @@ void MifareUltralightAppReset(void)
State = STATE_IDLE;
}
-void MifareUltralightAppTask(void)
-{
-
-}
-
static bool VerifyAuthentication(uint8_t PageAddress)
{
/* No authentication for EV0 cards; always pass */
@@ -200,7 +197,7 @@ static uint8_t AppWritePage(uint8_t PageAddress, uint8_t* const Buffer)
if (PageAddress == PAGE_LOCK_BITS || PageAddress == PAGE_OTP) {
// OTP page and page with locks could not be resets to zero
uint8_t PageBytes[MIFARE_ULTRALIGHT_PAGE_SIZE];
- AppMemoryRead(PageBytes, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE);
+ AppCardMemoryRead(PageBytes, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE);
// First two bytes of page with locks are not rewritable
if (PageAddress == PAGE_LOCK_BITS) {
Buffer[0] = Buffer[1] = 0;
@@ -209,7 +206,7 @@ static uint8_t AppWritePage(uint8_t PageAddress, uint8_t* const Buffer)
Buffer[i] |= PageBytes[i];
}
}
- AppMemoryWrite(Buffer, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE);
+ AppCardMemoryWrite(Buffer, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE);
} else {
/* If the chameleon is in read only mode, it silently
* ignores any attempt to write data. */
@@ -250,7 +247,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
}
/* Read out, emulating the wraparound */
for (Offset = 0; Offset < BYTES_PER_READ; Offset += 4) {
- AppMemoryRead(&Buffer[Offset], PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE);
+ AppCardMemoryRead(&Buffer[Offset], PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE);
PageAddress++;
if (PageAddress == PageLimit) {
PageAddress = 0;
@@ -319,7 +316,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
case CMD_GET_VERSION: {
/* Check new dump format and get version from out of pages area (skip 3 pages of counters) */
- AppMemoryRead(Buffer, (PageCount + VERSION_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, VERSION_INFO_LENGTH);
+ AppCardMemoryRead(Buffer, (PageCount + VERSION_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, VERSION_INFO_LENGTH);
if (Buffer[6] != 0x0B && Buffer[6] != 0x0E) {
/* Provide hardcoded version response */
Buffer[0] = 0x00;
@@ -352,7 +349,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
}
/* NOTE: With the current implementation, reading the password out is possible. */
ByteCount = (EndPageAddress - StartPageAddress + 1) * MIFARE_ULTRALIGHT_PAGE_SIZE;
- AppMemoryRead(Buffer, StartPageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, ByteCount);
+ AppCardMemoryRead(Buffer, StartPageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, ByteCount);
ISO14443AAppendCRCA(Buffer, ByteCount);
return (ByteCount + ISO14443A_CRCA_SIZE) * 8;
}
@@ -362,7 +359,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
uint8_t Password[4];
/* Save password */
- AppMemoryWrite(Buffer+1, MIFARE_ULTRALIGHT_PWD_ADDRESS, 4);
+ AppWorkingMemoryWrite(Buffer+1, MIFARE_ULTRALIGHT_PWD_ADDRESS, MIFARE_ULTRALIGHT_PWD_SIZE);
/* Verify value and increment authentication attempt counter */
if (!AuthCounterIncrement()) {
@@ -371,7 +368,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
return NAK_FRAME_SIZE;
}
/* Read and compare the password */
- AppMemoryRead(Password, ConfigAreaAddress + CONF_PASSWORD_OFFSET, 4);
+ AppCardMemoryRead(Password, ConfigAreaAddress + CONF_PASSWORD_OFFSET, 4);
if (Password[0] != Buffer[1] || Password[1] != Buffer[2] || Password[2] != Buffer[3] || Password[3] != Buffer[4]) {
Buffer[0] = NAK_AUTH_FAILED;
return NAK_FRAME_SIZE;
@@ -380,7 +377,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
AuthCounterReset();
Authenticated = 1;
/* Send the PACK value back */
- AppMemoryRead(Buffer, ConfigAreaAddress + CONF_PACK_OFFSET, 2);
+ AppCardMemoryRead(Buffer, ConfigAreaAddress + CONF_PACK_OFFSET, 2);
ISO14443AAppendCRCA(Buffer, 2);
return (2 + ISO14443A_CRCA_SIZE) * 8;
}
@@ -393,7 +390,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
return NAK_FRAME_SIZE;
}
/* Returned counter length is 3 bytes */
- AppMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE);
+ AppCardMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE);
ISO14443AAppendCRCA(Buffer, CNT_SIZE);
return (3 + ISO14443A_CRCA_SIZE) * 8;
}
@@ -408,7 +405,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
return NAK_FRAME_SIZE;
}
/* Read the value out */
- AppMemoryRead(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE);
+ AppCardMemoryRead(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE);
/* Add and check for overflow */
Counter += Addend;
if (Counter > CNT_MAX_VALUE) {
@@ -416,14 +413,14 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
return NAK_FRAME_SIZE;
}
/* Update memory */
- AppMemoryWrite(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE);
+ AppCardMemoryWrite(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE);
Buffer[0] = ACK_VALUE;
return ACK_FRAME_SIZE;
}
case CMD_READ_SIG: {
/* Check new dump format and get signature from out of pages area (skip 3 pages of counters, 2 pages VERSION) */
- AppMemoryRead(Buffer, (PageCount + SIGNATURE_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, SIGNATURE_LENGTH);
+ AppCardMemoryRead(Buffer, (PageCount + SIGNATURE_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, SIGNATURE_LENGTH);
uint8_t zeros[SIGNATURE_LENGTH];
memset(zeros, 0, SIGNATURE_LENGTH);
if (memcmp(Buffer, zeros, SIGNATURE_LENGTH) == 0) {
@@ -437,7 +434,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
case CMD_CHECK_TEARING_EVENT: {
uint8_t CounterId = Buffer[1];
/* Read tearing flag from counter pages of new dump format */
- AppMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE + CNT_SIZE, TEARING_SIZE);
+ AppCardMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE + CNT_SIZE, TEARING_SIZE);
/* Hardcoded response */
if (Buffer[0] == 0) {
Buffer[0] = 0xBD;
@@ -450,7 +447,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
uint8_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE;
/* Input is ignored completely */
/* Read out the value */
- AppMemoryRead(Buffer, ConfigAreaAddress + CONF_VCTID_OFFSET, 1);
+ AppCardMemoryRead(Buffer, ConfigAreaAddress + CONF_VCTID_OFFSET, 1);
ISO14443AAppendCRCA(Buffer, 1);
return (1 + ISO14443A_CRCA_SIZE) * 8;
}
@@ -491,7 +488,7 @@ uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount)
* of CL1 has to be the cascade-tag byte. */
uint8_t UidCL1[ISO14443A_CL_UID_SIZE] = { [0] = ISO14443A_UID0_CT };
- AppMemoryRead(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE);
+ AppCardMemoryRead(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE);
if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) {
/* CL1 stage has ended successfully */
@@ -503,7 +500,7 @@ uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount)
/* Load UID CL2 and perform anticollision */
uint8_t UidCL2[ISO14443A_CL_UID_SIZE];
- AppMemoryRead(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE);
+ AppCardMemoryRead(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE);
if (ISO14443ASelect(Buffer, &BitCount, UidCL2, SAK_CL2_VALUE)) {
/* CL2 stage has ended successfully. This means
@@ -552,8 +549,8 @@ uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount)
void MifareUltralightGetUid(ConfigurationUidType Uid)
{
/* Read UID from memory */
- AppMemoryRead(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
- AppMemoryRead(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
+ AppCardMemoryRead(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
+ AppCardMemoryRead(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
}
void MifareUltralightSetUid(ConfigurationUidType Uid)
@@ -562,28 +559,30 @@ void MifareUltralightSetUid(ConfigurationUidType Uid)
uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2];
uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6];
- AppMemoryWrite(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
- AppMemoryWrite(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
- AppMemoryWrite(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
- AppMemoryWrite(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
+ AppCardMemoryWrite(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
+ AppCardMemoryWrite(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
+ AppCardMemoryWrite(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
+ AppCardMemoryWrite(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
}
void MifareUltralightGetAtqa(uint16_t * Atqa)
{
- *Atqa = CardATQAValue;
+ *Atqa = CardATQAValue;
}
void MifareUltralightSetAtqa(uint16_t Atqa)
{
- CardATQAValue = Atqa;
+ CardATQAValue = Atqa;
}
void MifareUltralightGetSak(uint8_t * Sak)
{
- *Sak = CardSAKValue;
+ *Sak = CardSAKValue;
}
void MifareUltralightSetSak(uint8_t Sak)
{
- CardSAKValue = Sak;
+ CardSAKValue = Sak;
}
+
+#endif /* Compilation support */
diff --git a/Firmware/ChameleonMini/Application/MifareUltralight.h b/Firmware/ChameleonMini/Application/MifareUltralight.h
index 3c1157a..27e271d 100644
--- a/Firmware/ChameleonMini/Application/MifareUltralight.h
+++ b/Firmware/ChameleonMini/Application/MifareUltralight.h
@@ -5,27 +5,29 @@
* Author: skuser
*/
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+
#ifndef MIFAREULTRALIGHT_H_
#define MIFAREULTRALIGHT_H_
#include "Application.h"
#include "ISO14443-3A.h"
-#define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE
-#define MIFARE_ULTRALIGHT_PAGE_SIZE 4
-#define MIFARE_ULTRALIGHT_PAGES 16
-#define MIFARE_ULTRALIGHT_EV11_PAGES 20
-#define MIFARE_ULTRALIGHT_EV12_PAGES 41
+#define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE
+#define MIFARE_ULTRALIGHT_PAGE_SIZE 4
+#define MIFARE_ULTRALIGHT_PAGES 16
+#define MIFARE_ULTRALIGHT_EV11_PAGES 20
+#define MIFARE_ULTRALIGHT_EV12_PAGES 41
#define MIFARE_ULTRALIGHT_MEM_SIZE (MIFARE_ULTRALIGHT_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE)
#define MIFARE_ULTRALIGHT_EV11_MEM_SIZE (MIFARE_ULTRALIGHT_EV11_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE)
#define MIFARE_ULTRALIGHT_EV12_MEM_SIZE (MIFARE_ULTRALIGHT_EV12_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE)
-#define MIFARE_ULTRALIGHT_PWD_ADDRESS (MIFARE_ULTRALIGHT_EV12_MEM_SIZE + 100)
+#define MIFARE_ULTRALIGHT_PWD_ADDRESS 0 // In working memory
+#define MIFARE_ULTRALIGHT_PWD_SIZE 4 // Bytes
void MifareUltralightAppInit(void);
void MifareUltralightEV11AppInit(void);
void MifareUltralightEV12AppInit(void);
void MifareUltralightAppReset(void);
-void MifareUltralightAppTask(void);
uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount);
@@ -38,3 +40,5 @@ void MifareUltralightGetSak(uint8_t * Sak);
void MifareUltralightSetSak(uint8_t Sak);
#endif /* MIFAREULTRALIGHT_H_ */
+
+#endif /* Compilation support */
diff --git a/Firmware/ChameleonMini/Button.c b/Firmware/ChameleonMini/Button.c
index c10b173..774b766 100644
--- a/Firmware/ChameleonMini/Button.c
+++ b/Firmware/ChameleonMini/Button.c
@@ -14,6 +14,7 @@ static const char PROGMEM ButtonActionTable[][BUTTON_NAME_MAX_LEN] =
[BUTTON_ACTION_UID_RIGHT_DECREMENT] = "UID_RIGHT_DECREMENT",
[BUTTON_ACTION_CYCLE_SETTINGS] = "SWITCHCARD",
[BUTTON_ACTION_TOGGLE_READONLY] = "READONLY",
+ [BUTTON_ACTION_FUNCTION] = "CARD_FUNCTION",
};
void ButtonInit(void)
@@ -120,6 +121,8 @@ static void ExecuteButtonAction(ButtonActionEnum ButtonAction)
SettingsCycle();
} else if (ButtonAction == BUTTON_ACTION_TOGGLE_READONLY) {
ActiveConfiguration.ReadOnly = !ActiveConfiguration.ReadOnly;
+ } else if (ButtonAction == BUTTON_ACTION_FUNCTION) {
+ ApplicationButton();
}
}
diff --git a/Firmware/ChameleonMini/Button.h b/Firmware/ChameleonMini/Button.h
index b11d6cc..0115195 100644
--- a/Firmware/ChameleonMini/Button.h
+++ b/Firmware/ChameleonMini/Button.h
@@ -28,7 +28,7 @@ typedef enum {
BUTTON_ACTION_UID_RIGHT_DECREMENT,
BUTTON_ACTION_CYCLE_SETTINGS,
BUTTON_ACTION_TOGGLE_READONLY,
-
+ BUTTON_ACTION_FUNCTION,
/* This has to be last element */
BUTTON_ACTION_COUNT
} ButtonActionEnum;
diff --git a/Firmware/ChameleonMini/ChameleonMini.c b/Firmware/ChameleonMini/ChameleonMini.c
index 16eadba..3e96c98 100644
--- a/Firmware/ChameleonMini/ChameleonMini.c
+++ b/Firmware/ChameleonMini/ChameleonMini.c
@@ -1,27 +1,29 @@
#include "ChameleonMini.h"
int main(void) {
- SystemInit();
- MemoryInit();
- SettingsLoad();
- LEDInit();
- ConfigurationInit();
- TerminalInit();
- RandomInit();
- ButtonInit();
- AntennaLevelInit();
- SystemInterruptInit();
+ SystemInit();
+ MemoryInit();
+ SettingsLoad();
+ LEDInit();
+ ConfigurationInit();
+ TerminalInit();
+ RandomInit();
+ ButtonInit();
+ AntennaLevelInit();
+ SystemInterruptInit();
- while(1) {
- TerminalTask();
- CodecTask();
- ApplicationTask();
-
- if (SystemTick100ms()) {
- RandomTick();
- TerminalTick();
- ButtonTick();
- LEDTick();
- }
- }
+ while(1) {
+ if (SystemTick100ms()) {
+ LEDTick();
+ RandomTick();
+ TerminalTick();
+ ButtonTick();
+ ApplicationTick();
+ //CommandLineTick();
+ //AntennaLevelTick();
+ }
+ TerminalTask();
+ CodecTask();
+ //ApplicationTask();
+ }
}
diff --git a/Firmware/ChameleonMini/ChameleonMini.cproj b/Firmware/ChameleonMini/ChameleonMini.cproj
index bf9c2bd..c69534c 100644
--- a/Firmware/ChameleonMini/ChameleonMini.cproj
+++ b/Firmware/ChameleonMini/ChameleonMini.cproj
@@ -222,9 +222,8 @@
DEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS
DEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_CYCLE_SETTINGS
CONFIG_MF_ULTRALIGHT_SUPPORT
- CONFIG_MF_CLASSIC_1K_SUPPORT
- CONFIG_MF_CLASSIC_4K_SUPPORT
- CONFIG_MF_DETECTION_SUPPORT
+ CONFIG_MF_CLASSIC_SUPPORT
+ CONFIG_MF_CLASSIC_DETECTION_SUPPORT
SUPPORT_FIRMWARE_UPGRADE
@@ -281,9 +280,8 @@
DEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS
DEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_CYCLE_SETTINGS
CONFIG_MF_ULTRALIGHT_SUPPORT
- CONFIG_MF_CLASSIC_1K_SUPPORT
- CONFIG_MF_CLASSIC_4K_SUPPORT
- CONFIG_MF_DETECTION_SUPPORT
+ CONFIG_MF_CLASSIC_SUPPORT
+ CONFIG_MF_CLASSIC_DETECTION_SUPPORT
SUPPORT_FIRMWARE_UPGRADE
diff --git a/Firmware/ChameleonMini/Configuration.c b/Firmware/ChameleonMini/Configuration.c
index 5875e7b..597dca8 100644
--- a/Firmware/ChameleonMini/Configuration.c
+++ b/Firmware/ChameleonMini/Configuration.c
@@ -6,6 +6,7 @@
*/
#include
+#include "Memory/Memory.h"
#include "Configuration.h"
#include "Settings.h"
#include "Map.h"
@@ -18,23 +19,21 @@ static const MapEntryType ConfigurationMap[] PROGMEM = {
{ .Id = CONFIG_MF_ULTRALIGHT_EV1_80B, .Text = "MF_ULTRALIGHT_EV1_80B" },
{ .Id = CONFIG_MF_ULTRALIGHT_EV1_164B, .Text = "MF_ULTRALIGHT_EV1_164B" },
#endif
-#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_1K, .Text = "MF_CLASSIC_1K" },
-#endif
-#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_1K_7B, .Text = "MF_CLASSIC_1K_7B" },
-#endif
-#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_4K, .Text = "MF_CLASSIC_4K" },
-#endif
-#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_4K_7B, .Text = "MF_CLASSIC_4K_7B" },
-#endif
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_MINI, .Text = "MF_CLASSIC_MINI" },
#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
- { .Id = CONFIG_MF_DETECTION, .Text = "MF_DETECTION" },
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
+ { .Id = CONFIG_MF_CLASSIC_DETECTION, .Text = "MF_CLASSIC_DETECTION" },
+#endif
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+ { .Id = CONFIG_MF_CLASSIC_BRUTE, .Text = "MF_CLASSIC_BRUTE" },
+#endif
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+ { .Id = CONFIG_MF_CLASSIC_LOG, .Text = "MF_CLASSIC_LOG" },
#endif
};
@@ -48,6 +47,7 @@ static void ApplicationInitDummy(void) {}
static void ApplicationResetDummy(void) {}
static void ApplicationTaskDummy(void) {}
static void ApplicationTickDummy(void) {}
+static void ApplicationButtonFuncDummy(void) {}
static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return CONFIGURATION_DUMMY_UID_PART; }
static void ApplicationGetUidDummy(ConfigurationUidType Uid) { memset(Uid, CONFIGURATION_DUMMY_UID_PART, CONFIGURATION_DUMMY_UID_SIZE); }
static void ApplicationSetUidDummy(ConfigurationUidType Uid) { }
@@ -64,6 +64,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationResetFunc = ApplicationResetDummy,
.ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = ApplicationProcessDummy,
.ApplicationGetUidFunc = ApplicationGetUidDummy,
.ApplicationSetUidFunc = ApplicationSetUidDummy,
@@ -72,7 +73,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = ApplicationGetAtqaDummy,
.ApplicationSetAtqaFunc = ApplicationSetAtqaDummy,
.UidSize = CONFIGURATION_DUMMY_UID_SIZE,
- .MemorySize = CONFIGURATION_DUMMY_MEMSIZE,
+ .CardMemorySize = CONFIGURATION_DUMMY_MEMSIZE,
+ .WorkingMemorySize = MEMORY_NO_MEMORY,
.ReadOnly = true
},
#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
@@ -81,8 +83,9 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareUltralightAppInit,
.ApplicationResetFunc = MifareUltralightAppReset,
- .ApplicationTaskFunc = MifareUltralightAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
@@ -91,7 +94,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
- .MemorySize = MIFARE_ULTRALIGHT_MEM_SIZE,
+ .CardMemorySize = MIFARE_ULTRALIGHT_MEM_SIZE,
+ .WorkingMemorySize = MIFARE_ULTRALIGHT_PWD_SIZE,
.ReadOnly = false
},
[CONFIG_MF_ULTRALIGHT_EV1_80B] = {
@@ -99,8 +103,9 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareUltralightEV11AppInit,
.ApplicationResetFunc = MifareUltralightAppReset,
- .ApplicationTaskFunc = MifareUltralightAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
@@ -109,7 +114,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
- .MemorySize = MIFARE_ULTRALIGHT_EV11_MEM_SIZE,
+ .CardMemorySize = MIFARE_ULTRALIGHT_EV11_MEM_SIZE,
+ .WorkingMemorySize = MIFARE_ULTRALIGHT_PWD_SIZE,
.ReadOnly = false
},
[CONFIG_MF_ULTRALIGHT_EV1_164B] = {
@@ -117,8 +123,9 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareUltralightEV12AppInit,
.ApplicationResetFunc = MifareUltralightAppReset,
- .ApplicationTaskFunc = MifareUltralightAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
@@ -127,18 +134,20 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
- .MemorySize = MIFARE_ULTRALIGHT_EV12_MEM_SIZE,
+ .CardMemorySize = MIFARE_ULTRALIGHT_EV12_MEM_SIZE,
+ .WorkingMemorySize = MIFARE_ULTRALIGHT_PWD_SIZE,
.ReadOnly = false
},
#endif
-#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_SUPPORT
[CONFIG_MF_CLASSIC_1K] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppInit1K,
.ApplicationResetFunc = MifareClassicAppReset,
- .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
@@ -147,18 +156,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_SIZE,
- .MemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .CardMemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .WorkingMemorySize = MEMORY_NO_MEMORY,
.ReadOnly = false
},
-#endif
-#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT
[CONFIG_MF_CLASSIC_1K_7B] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppInit1K,
.ApplicationResetFunc = MifareClassicAppReset,
- .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
@@ -167,18 +176,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_7B_SIZE,
- .MemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .CardMemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .WorkingMemorySize = MEMORY_NO_MEMORY,
.ReadOnly = false
},
-#endif
-#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
[CONFIG_MF_CLASSIC_4K] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppInit4K,
.ApplicationResetFunc = MifareClassicAppReset,
- .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
@@ -187,18 +196,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_SIZE,
- .MemorySize = MFCLASSIC_4K_MEM_SIZE,
+ .CardMemorySize = MFCLASSIC_4K_MEM_SIZE,
+ .WorkingMemorySize = MEMORY_NO_MEMORY,
.ReadOnly = false
},
-#endif
-#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT
[CONFIG_MF_CLASSIC_4K_7B] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppInit4K,
.ApplicationResetFunc = MifareClassicAppReset,
- .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
@@ -207,18 +216,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_7B_SIZE,
- .MemorySize = MFCLASSIC_4K_MEM_SIZE,
+ .CardMemorySize = MFCLASSIC_4K_MEM_SIZE,
+ .WorkingMemorySize = MEMORY_NO_MEMORY,
.ReadOnly = false
},
-#endif
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
[CONFIG_MF_CLASSIC_MINI] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppInitMini,
.ApplicationResetFunc = MifareClassicAppReset,
- .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
@@ -227,18 +236,20 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_SIZE,
- .MemorySize = MFCLASSIC_MINI_MEM_SIZE,
+ .CardMemorySize = MFCLASSIC_MINI_MEM_SIZE,
+ .WorkingMemorySize = MEMORY_NO_MEMORY,
.ReadOnly = false
},
#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
-[CONFIG_MF_DETECTION] = {
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
+[CONFIG_MF_CLASSIC_DETECTION] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppDetectionInit,
.ApplicationResetFunc = MifareClassicAppReset,
- .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationButtonFunc = ApplicationButtonFuncDummy,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
@@ -247,8 +258,53 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_SIZE,
- .MemorySize = DETECTION_MEM_APP_SIZE,
- .ReadOnly = true
+ .CardMemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .WorkingMemorySize = DETECTION_MEM_APP_SIZE,
+ .ReadOnly = false
+},
+#endif
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+[CONFIG_MF_CLASSIC_BRUTE] = {
+ .CodecInitFunc = ISO14443ACodecInit,
+ .CodecTaskFunc = ISO14443ACodecTask,
+ .ApplicationInitFunc = MifareClassicAppBruteInit,
+ .ApplicationResetFunc = MifareClassicAppReset,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
+ .ApplicationTickFunc = MifareClassicAppBruteTick,
+ .ApplicationButtonFunc = MifareClassicAppBruteToggle,
+ .ApplicationProcessFunc = MifareClassicAppProcess,
+ .ApplicationGetUidFunc = MifareClassicGetUid,
+ .ApplicationSetUidFunc = MifareClassicSetUid,
+ .ApplicationGetSakFunc = MifareClassicGetSak,
+ .ApplicationSetSakFunc = MifareClassicSetSak,
+ .ApplicationGetAtqaFunc = MifareClassicGetAtqa,
+ .ApplicationSetAtqaFunc = MifareClassicSetAtqa,
+ .UidSize = MFCLASSIC_UID_SIZE,
+ .CardMemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .WorkingMemorySize = BRUTE_WORKING_MEM_SIZE,
+ .ReadOnly = false
+},
+#endif
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+[CONFIG_MF_CLASSIC_LOG] = {
+ .CodecInitFunc = ISO14443ACodecInit,
+ .CodecTaskFunc = ISO14443ACodecTask,
+ .ApplicationInitFunc = MifareClassicAppLogInit,
+ .ApplicationResetFunc = MifareClassicAppReset,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
+ .ApplicationTickFunc = MifareClassicAppLogWriteLines,
+ .ApplicationButtonFunc = MifareClassicAppLogToggle,
+ .ApplicationProcessFunc = MifareClassicAppProcess,
+ .ApplicationGetUidFunc = MifareClassicGetUid,
+ .ApplicationSetUidFunc = MifareClassicSetUid,
+ .ApplicationGetSakFunc = MifareClassicGetSak,
+ .ApplicationSetSakFunc = MifareClassicSetSak,
+ .ApplicationGetAtqaFunc = MifareClassicGetAtqa,
+ .ApplicationSetAtqaFunc = MifareClassicSetAtqa,
+ .UidSize = MFCLASSIC_UID_SIZE,
+ .CardMemorySize = MFCLASSIC_1K_MEM_SIZE,
+ .WorkingMemorySize = MEMORY_ALL_MEMORY,
+ .ReadOnly = false
},
#endif
};
@@ -292,14 +348,10 @@ void ConfigurationGetList(char* List, uint16_t BufferSize)
MapToString(ConfigurationMap, ARRAY_COUNT(ConfigurationMap), List, BufferSize);
}
-uint32_t ConfigurationTableGetMemorySizeForId(ConfigurationEnum Configuration) {
- /* Possible other implementation
- ConfigurationType ConfForSetting;
- memcpy_P( &ConfForSetting,
- &(ConfigurationTable[GlobalSettings.Settings[SettingNumber].Configuration]),
- sizeof(ConfigurationType) );
- return ConfForSetting.MemorySize;
- */
- return ( (uint32_t)pgm_read_dword( &(ConfigurationTable[Configuration].MemorySize) ) );
+uint32_t ConfigurationTableGetCardMemorySizeForId(ConfigurationEnum Configuration) {
+ return ( (uint32_t)pgm_read_dword( &(ConfigurationTable[Configuration].CardMemorySize) ) );
}
+uint32_t ConfigurationTableGetWorkingMemorySizeForId(ConfigurationEnum Configuration) {
+ return ( (uint32_t)pgm_read_dword( &(ConfigurationTable[Configuration].WorkingMemorySize) ) );
+}
diff --git a/Firmware/ChameleonMini/Configuration.h b/Firmware/ChameleonMini/Configuration.h
index 86a794d..8b53599 100644
--- a/Firmware/ChameleonMini/Configuration.h
+++ b/Firmware/ChameleonMini/Configuration.h
@@ -29,23 +29,21 @@ typedef enum {
CONFIG_MF_ULTRALIGHT_EV1_80B,
CONFIG_MF_ULTRALIGHT_EV1_164B,
#endif
-#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_SUPPORT
CONFIG_MF_CLASSIC_1K,
-#endif
-#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT
CONFIG_MF_CLASSIC_1K_7B,
-#endif
-#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
CONFIG_MF_CLASSIC_4K,
-#endif
-#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT
CONFIG_MF_CLASSIC_4K_7B,
-#endif
-#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT
CONFIG_MF_CLASSIC_MINI,
#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
- CONFIG_MF_DETECTION,
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
+ CONFIG_MF_CLASSIC_DETECTION,
+#endif
+#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
+ CONFIG_MF_CLASSIC_BRUTE,
+#endif
+#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
+ CONFIG_MF_CLASSIC_LOG,
#endif
/* This HAS to be the last element */
CONFIG_COUNT
@@ -85,6 +83,8 @@ typedef struct {
void (*ApplicationTaskFunc) (void);
/** Function that is called roughly every 100ms. This can be used for parallel tasks of the application, that is independent of the codec module. */
void (*ApplicationTickFunc) (void);
+ /** Function that is called when the "CARD_FUNCTION" button is pushed */
+ void (*ApplicationButtonFunc) (void);
/** This function does two important things. It gets called by the codec.
* The first task is to deliver data that have been received by the codec module to
* the application module. The application then can decide how to answer to these data and return
@@ -131,11 +131,10 @@ typedef struct {
* @}
*/
- /**
- * Defines how many space the configuration needs. For emulating configurations this is the memory space of
- * the emulated card.
- */
- uint32_t MemorySize;
+ // Defines how many space the configuration needs to store card emulation data.
+ uint32_t CardMemorySize;
+ // Defines how many space the configuration needs to store working data (logs, results, etc.)
+ uint32_t WorkingMemorySize;
/**
* Defines the size of the UID for emulating configurations.
*/
@@ -154,6 +153,7 @@ void ConfigurationSetById(ConfigurationEnum Configuration);
void ConfigurationGetByName(char* Configuration, uint16_t BufferSize);
bool ConfigurationSetByName(const char* Configuration);
void ConfigurationGetList(char* ConfigurationList, uint16_t BufferSize);
-uint32_t ConfigurationTableGetMemorySizeForId(ConfigurationEnum Configuration);
+uint32_t ConfigurationTableGetCardMemorySizeForId(ConfigurationEnum Configuration);
+uint32_t ConfigurationTableGetWorkingMemorySizeForId(ConfigurationEnum Configuration);
#endif /* _CM_CONFIGURATION_H_ */
diff --git a/Firmware/ChameleonMini/Makefile b/Firmware/ChameleonMini/Makefile
index 9575b04..574f54b 100644
--- a/Firmware/ChameleonMini/Makefile
+++ b/Firmware/ChameleonMini/Makefile
@@ -16,67 +16,30 @@ PYTHON_BIN = /usr/bin/env python3
CRYPTO_TOOL = ../../Software/Tools/crypt_operations.py
#Supported configurations
-SETTINGS += -DCONFIG_MF_CLASSIC_1K_SUPPORT
-SETTINGS += -DCONFIG_MF_CLASSIC_1K_7B_SUPPORT
-SETTINGS += -DCONFIG_MF_CLASSIC_4K_SUPPORT
-SETTINGS += -DCONFIG_MF_CLASSIC_4K_7B_SUPPORT
-SETTINGS += -DCONFIG_MF_CLASSIC_MINI_SUPPORT
+SETTINGS += -DCONFIG_MF_CLASSIC_SUPPORT
SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT
-#SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT
-#SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT
-SETTINGS += -DCONFIG_MF_DETECTION_SUPPORT
+SETTINGS += -DCONFIG_MF_CLASSIC_DETECTION_SUPPORT
+#SETTINGS += -DCONFIG_MF_CLASSIC_BRUTE_SUPPORT
+#SETTINGS += -DCONFIG_MF_CLASSIC_LOG_SUPPORT
#Support magic mode on mifare classic configuration
#SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE
-#Don't touch manufacturer byte with BUTTON_ACTION_UID_LEFT_(DE/IN)CREMENT
-#SETTINGS += -DSUPPORT_UID7_FIX_MANUFACTURER_BYTE
-
#Support activating firmware upgrade mode through command-line
SETTINGS += -DSUPPORT_FIRMWARE_UPGRADE
#Enable the MEMORYTEST and/or MEMORYINFO commands to help with memory management debug
-#SETTINGS += -DCONFIG_DEBUG_MEMORYTEST_COMMAND
-#SETTINGS += -DCONFIG_DEBUG_MEMORYINFO_COMMAND
+SETTINGS += -DCONFIG_DEBUG_MEMORYTEST_COMMAND
+SETTINGS += -DCONFIG_DEBUG_MEMORYINFO_COMMAND
#Default configuration
SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_NONE
-#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_1K
-#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_4K
-#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_ULTRALIGHT
-#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_ISO14443A_READER
#Default button actions
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_NONE
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RANDOM
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_INCREMENT
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_INCREMENT
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_DECREMENT
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_DECREMENT
SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS
-#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_STORE_MEM
-
#Default long button action
SETTINGS += -DDEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_NONE
-#Define if button action setting should be independent of active setting
-#SETTINGS += -DBUTTON_SETTING_GLOBAL
-
-#Default LED functions
-#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_SETTING_CHANGE
-#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_POWERED
-
-#Define if LED function setting should be independent of active setting
-#SETTINGS += -DLED_SETTING_GLOBAL
-
-#Default logging mode
-#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_OFF
-#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_MEMORY
-#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_TERMINAL
-
-#Define if log settings should be global
-#SETTINGS += -DLOG_SETTING_GLOBAL
-
#Default setting
SETTINGS += -DDEFAULT_SETTING=0
diff --git a/Firmware/ChameleonMini/Memory/Memory.c b/Firmware/ChameleonMini/Memory/Memory.c
index d6c9037..b49503e 100644
--- a/Firmware/ChameleonMini/Memory/Memory.c
+++ b/Firmware/ChameleonMini/Memory/Memory.c
@@ -18,44 +18,87 @@
#include "../Configuration.h"
#include "../Application/Application.h"
-// Set after correct memory init
-static bool isMemoryInit = false;
+memoryMappingInfo_t MemoryMappingInfo = {MEMORY_NO_MEMORY, MEMORY_NO_MEMORY, MEMORY_NO_MEMORY, false};
/* Common helpers for memory operations
***************************************************************************************/
-// How much memory a setting's application will take. If set to 0 or to more than possible,
-// pretend that max available memory for a setting/slot is used.
-// Otherwise, give what is required by setting's configuration value 'MemorySize'.
-INLINE uint32_t getAppMemSizeForSetting(uint8_t SettingNumber) {
- uint16_t requiredMem = ConfigurationTableGetMemorySizeForId(GlobalSettings.Settings[SettingNumber].Configuration);
- if( (requiredMem == MEMORY_NO_MEMORY) || (requiredMem > MemoryMappingInfo.maxFlashBytesPerSlot) ) {
- requiredMem = MemoryMappingInfo.maxFlashBytesPerSlot;
+// How much memory a setting's application will take. If set to MEMORY_ALL_MEMORY
+// or to more than possible, use max available memory.
+// Otherwise, give what is required by setting's configuration values.
+uint32_t getAppSomeMemorySizeForSetting(uint32_t availMem, uint32_t requiredMem) {
+ if( (requiredMem == MEMORY_ALL_MEMORY) || (requiredMem > availMem) ) {
+ requiredMem = availMem;
}
return requiredMem;
}
-INLINE bool checkSettingNumberConsistency(uint8_t SettingNumber) {
- return ( (SettingNumber >= SETTINGS_FIRST) && (SettingNumber <= SETTINGS_LAST) );
+uint32_t AppCardMemorySizeForSetting(uint8_t SettingNumber) {
+ uint32_t requiredMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (ActiveConfiguration.CardMemorySize) : (ConfigurationTableGetCardMemorySizeForId(GlobalSettings.Settings[SettingNumber].Configuration));
+ return getAppSomeMemorySizeForSetting( MemoryMappingInfo.maxFlashBytesPerCardMemory, requiredMem);
+}
+
+uint32_t AppWorkingMemorySizeForSetting(uint8_t SettingNumber) {
+ uint32_t requiredMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (ActiveConfiguration.WorkingMemorySize) : (ConfigurationTableGetWorkingMemorySizeForId(GlobalSettings.Settings[SettingNumber].Configuration));
+ return getAppSomeMemorySizeForSetting( (MemoryMappingInfo.maxFlashBytesPerSlot - AppCardMemorySizeForSetting(SettingNumber)), requiredMem );
+}
+
+uint32_t AppCardMemorySize(void) {
+ return AppCardMemorySizeForSetting(GlobalSettings.ActiveSetting);
+}
+
+uint32_t AppWorkingMemorySize(void) {
+ return AppWorkingMemorySizeForSetting(GlobalSettings.ActiveSetting);
+}
+
+uint32_t AppMemorySizeForSetting(uint8_t SettingNumber) {
+ return (AppCardMemorySizeForSetting(SettingNumber) + AppWorkingMemorySizeForSetting(SettingNumber));
+}
+
+uint32_t AppMemorySize(void) {
+ return AppMemorySizeForSetting(GlobalSettings.ActiveSetting);
+}
+
+bool checkSettingNumberConsistency(uint8_t SettingNumber) {
+ return ( (SettingNumber == GlobalSettings.ActiveSetting) || ((SettingNumber >= SETTINGS_FIRST) && (SettingNumber <= SETTINGS_LAST)) );
}
// Is an address start + offset R/W operation valid in setting's application memory space
-INLINE bool checkAddrConsistencyForSetting(uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) {
- bool ret = (isMemoryInit && checkSettingNumberConsistency(SettingNumber));
- if(ret) {
- ret = (Address <= (getAppMemSizeForSetting(SettingNumber) - ByteCount));
+bool checkAddrConsistencyForSetting(uint32_t availMem, uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) {
+ bool ret = false;
+ if( MemoryMappingInfo.isMemoryInit && checkSettingNumberConsistency(SettingNumber)
+ && (availMem > MEMORY_NO_MEMORY) && (availMem >= ByteCount)) {
+ ret = (Address <= (availMem - ByteCount));
}
return ret;
}
+bool checkCardMemAddrConsistencyForSetting(uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) {
+ uint32_t availMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (AppCardMemorySize()) : (AppCardMemorySizeForSetting(SettingNumber));
+ return checkAddrConsistencyForSetting(availMem, SettingNumber, Address, ByteCount);
+}
+
+bool checkWorkingMemAddrConsistencyForSetting(uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) {
+ uint32_t availMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (AppWorkingMemorySize()) : (AppWorkingMemorySizeForSetting(SettingNumber));
+ return checkAddrConsistencyForSetting(availMem, SettingNumber, Address, ByteCount);;
+}
+
// Returns a byte address in SPI Flash from a byte address relative to application's
// memory space.
// Does not check for address validity in application's space (checkSettingAddrConsistency
// must be used if needed).
-INLINE uint32_t getFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) {
+uint32_t getFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) {
return ((uint32_t)(SettingNumber * MemoryMappingInfo.maxFlashBytesPerSlot) + Address);
}
+uint32_t getCardMemFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) {
+ return getFlashAddressForSetting(SettingNumber, Address);
+}
+
+uint32_t getWorkingMemFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) {
+ return getFlashAddressForSetting(SettingNumber, (AppCardMemorySizeForSetting(SettingNumber) + Address));
+}
+
/* Memory init operations
***************************************************************************************/
@@ -65,10 +108,12 @@ bool MemoryInit(void) {
bool eepromOk = false;
if( FlashInit() ) {
MemoryMappingInfo.maxFlashBytesPerSlot = (FlashInfo.geometry.sizeBytes / SETTINGS_COUNT);
- if( MemoryMappingInfo.maxFlashBytesPerSlot >= MEMORY_MIN_BYTES_PER_APP ) {
+ MemoryMappingInfo.maxFlashBytesPerCardMemory = (MemoryMappingInfo.maxFlashBytesPerSlot / MEMORY_MAX_BYTES_PER_CARD_DIVIDER);
+ if( MemoryMappingInfo.maxFlashBytesPerCardMemory >= MEMORY_MIN_BYTES_PER_APP ) {
flashOk = true;
} else {
MemoryMappingInfo.maxFlashBytesPerSlot = MEMORY_NO_MEMORY;
+ MemoryMappingInfo.maxFlashBytesPerCardMemory = MEMORY_NO_MEMORY;
}
}
if( EEPROMInit() ) {
@@ -79,60 +124,111 @@ bool MemoryInit(void) {
MemoryMappingInfo.maxFlashBytesPerSlot = MEMORY_NO_MEMORY;
}
}
- isMemoryInit = (flashOk && eepromOk);
- return isMemoryInit;
+ MemoryMappingInfo.isMemoryInit = (flashOk && eepromOk);
+ return MemoryMappingInfo.isMemoryInit;
}
+
/* Memory read operations
***************************************************************************************/
-bool AppMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount) {
+bool AppMemoryReadForSetting( bool (*checkAddr)(uint8_t, uint32_t, uint32_t),
+ uint32_t (*getAddr)(uint8_t, uint32_t),
+ uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount ) {
bool ret = false;
- if( checkAddrConsistencyForSetting(SettingNumber, Address, ByteCount) ) {
- ret = FlashUnbufferedBytesRead(Buffer, getFlashAddressForSetting(SettingNumber, Address), ByteCount);
+ if( (*checkAddr)(SettingNumber, Address, ByteCount) ) {
+ ret = FlashUnbufferedBytesRead(Buffer, (*getAddr)(SettingNumber, Address), ByteCount);
}
return ret;
}
-bool AppMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount) {
- return AppMemoryReadForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount);
+bool AppCardMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryReadForSetting( &checkCardMemAddrConsistencyForSetting, &getCardMemFlashAddressForSetting,
+ SettingNumber, Buffer, Address, ByteCount );
+}
+
+bool AppWorkingMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryReadForSetting( &checkWorkingMemAddrConsistencyForSetting, &getWorkingMemFlashAddressForSetting,
+ SettingNumber, Buffer, Address, ByteCount );
+}
+
+bool AppCardMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppCardMemoryReadForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount);
+}
+
+bool AppWorkingMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppWorkingMemoryReadForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount);
}
-bool AppMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+bool AppMemoryDownloadXModem( uint32_t (*getSize)(void), bool (*memRead)(void*, uint32_t, uint32_t),
+ void* Buffer, uint32_t Address, uint32_t ByteCount ) {
bool ret = false;
- uint32_t AvailBytes = getAppMemSizeForSetting(GlobalSettings.ActiveSetting);
+ uint32_t AvailBytes = (*getSize)();
if(Address < AvailBytes) {
uint32_t BytesLeft = MIN(ByteCount, AvailBytes - Address);
- ret = AppMemoryRead(Buffer, Address, BytesLeft);
+ ret = (*memRead)(Buffer, Address, BytesLeft);
}
return ret;
}
+bool AppCardMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryDownloadXModem( &AppCardMemorySize, &AppCardMemoryRead, Buffer, Address, ByteCount);
+}
+
+bool AppWorkingMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryDownloadXModem( &AppWorkingMemorySize, &AppWorkingMemoryRead, Buffer, Address, ByteCount);
+}
+
/* Memory write operations
***************************************************************************************/
-bool AppMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount) {
+bool AppMemoryWriteForSetting( bool (*checkAddr)(uint8_t, uint32_t, uint32_t),
+ uint32_t (*getAddr)(uint8_t, uint32_t),
+ uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount ) {
bool ret = false;
- if( checkAddrConsistencyForSetting(SettingNumber, Address, ByteCount) ) {
- ret = FlashBufferedBytesWrite(Buffer, getFlashAddressForSetting(SettingNumber, Address), ByteCount);
+ if( (*checkAddr)(SettingNumber, Address, ByteCount) ) {
+ ret = FlashBufferedBytesWrite(Buffer, (*getAddr)(SettingNumber, Address), ByteCount);
}
return ret;
}
-bool AppMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount) {
- return AppMemoryWriteForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount);
+bool AppCardMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryWriteForSetting( &checkCardMemAddrConsistencyForSetting, &getCardMemFlashAddressForSetting,
+ SettingNumber, Buffer, Address, ByteCount );
+}
+
+bool AppWorkingMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryWriteForSetting( &checkWorkingMemAddrConsistencyForSetting, &getWorkingMemFlashAddressForSetting,
+ SettingNumber, Buffer, Address, ByteCount );
}
-bool AppMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+bool AppCardMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppCardMemoryWriteForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount);
+}
+
+bool AppWorkingMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppWorkingMemoryWriteForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount);
+}
+
+bool AppMemoryUploadXModem( uint32_t (*getSize)(void), bool (*memWrite)(const void*, uint32_t, uint32_t),
+ void* Buffer, uint32_t Address, uint32_t ByteCount ) {
bool ret = false;
- uint32_t AvailBytes = getAppMemSizeForSetting(GlobalSettings.ActiveSetting);
+ uint32_t AvailBytes = (*getSize)();
if(Address < AvailBytes) {
uint32_t BytesLeft = MIN(ByteCount, AvailBytes - Address);
- ret = AppMemoryWrite((const void *)Buffer, Address, BytesLeft);
+ ret = (*memWrite)((const void *)Buffer, Address, BytesLeft);
}
return ret;
}
+bool AppCardMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryUploadXModem( &AppCardMemorySize, &AppCardMemoryWrite, Buffer, Address, ByteCount);
+}
+
+bool AppWorkingMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) {
+ return AppMemoryUploadXModem( &AppWorkingMemorySize, &AppWorkingMemoryWrite, Buffer, Address, ByteCount);
+}
+
/* Memory delete/clear operations
***************************************************************************************/
@@ -143,14 +239,34 @@ bool MemoryClearAll(void) {
return (flashOK && eepromOK);
}
-bool AppMemoryClearForSetting(uint8_t SettingNumber) {
+bool AppSomeMemoryClearForSetting(uint8_t SettingNumber, uint32_t startAddress, uint32_t ByteCount) {
bool ret = false;
if( checkSettingNumberConsistency(SettingNumber) ) {
- ret = FlashClearRange( getFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), getAppMemSizeForSetting(SettingNumber) );
+ ret = FlashClearRange( startAddress, ByteCount );
}
return ret;
}
+bool AppMemoryClearForSetting(uint8_t SettingNumber) {
+ return AppSomeMemoryClearForSetting(SettingNumber, getFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), AppMemorySizeForSetting(SettingNumber));
+}
+
bool AppMemoryClear(void) {
return AppMemoryClearForSetting(GlobalSettings.ActiveSetting);
}
+
+bool AppCardMemoryClearForSetting(uint8_t SettingNumber) {
+ return AppSomeMemoryClearForSetting(SettingNumber, getCardMemFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), AppCardMemorySizeForSetting(SettingNumber));
+}
+
+bool AppWorkingMemoryClearForSetting(uint8_t SettingNumber) {
+ return AppSomeMemoryClearForSetting(SettingNumber, getWorkingMemFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), AppWorkingMemorySizeForSetting(SettingNumber));
+}
+
+bool AppCardMemoryClear(void) {
+ return AppCardMemoryClearForSetting(GlobalSettings.ActiveSetting);
+}
+
+bool AppWorkingMemoryClear(void) {
+ return AppWorkingMemoryClearForSetting(GlobalSettings.ActiveSetting);
+}
diff --git a/Firmware/ChameleonMini/Memory/Memory.h b/Firmware/ChameleonMini/Memory/Memory.h
index 1277dce..0ba7da0 100644
--- a/Firmware/ChameleonMini/Memory/Memory.h
+++ b/Firmware/ChameleonMini/Memory/Memory.h
@@ -16,47 +16,76 @@
#include "../Application/MifareClassic.h" // Just to define constants
#define MEMORY_NO_MEMORY 0x00
+#define MEMORY_ALL_MEMORY 0xFFFFFFFF
#define MEMORY_NO_ADDR 0
-#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_SUPPORT
#define MEMORY_MIN_BYTES_PER_APP MFCLASSIC_4K_MEM_SIZE
#else
-#define MEMORY_MIN_BYTES_PER_APP MFCLASSIC_1K_MEM_SIZE
+#define MEMORY_MIN_BYTES_PER_APP 512
#endif
+#define MEMORY_MAX_BYTES_PER_CARD_DIVIDER 8
#define MEMORY_MIN_BYTES_PER_SETTING (sizeof(SettingsEntryType)+sizeof(SettingsType))
typedef struct {
uint32_t maxFlashBytesPerSlot;
+ uint32_t maxFlashBytesPerCardMemory;
uint16_t maxEEPROMBytesPerSlot;
-
+ bool isMemoryInit;
} memoryMappingInfo_t;
-memoryMappingInfo_t MemoryMappingInfo;
+extern memoryMappingInfo_t MemoryMappingInfo;
bool MemoryInit(void);
/*
+*
+* Application/Config/Slot memory is divided in 2 separate spaces:
+* - CardMemory to store card emulation data,
+* - WorkingMemory to store internal application's data (logs, results, states, etc.).
+*
* By default all operations are relative to current active setting's application memory
* space.
* Functions that end with "ForSetting" can be used to operate on a specified setting's
* application memory space, regardless of the active setting.
*
-* We equally divides total SPI Flash memory space for each setting/slot's application
-* dedicated memory space.
-* But we will actually use setting's configuration required memory only, by default, except
-* when full available space is required, either by requiring 0 memory in setting's
-* configuration, or by requiring more than total available memory per setting/slot.
+* We equally divides total SPI Flash memory space for each slot's application.
+* CardMemory max amount is limited by MemoryMappingInfo.maxFlashBytesPerCardMemory.
+* WorkingMemory is limited by all available slot's memory
+* (MemoryMappingInfo.maxFlashBytesPerSlot) minus CardMemory.
+* Memory spaces sizes are set in configuration definition.
+* When MEMORY_ALL_MEMORY memory is set for a memory space, or if required memory is more
+* than possible, then memory space will be given the maximum memory amount.
+* As so, any memory operation should be based on this module memory spaces sizes results,
+* and not on configuration constants for memory sizes.
*/
-bool AppMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount);
-bool AppMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount);
-bool AppMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount);
+uint32_t AppCardMemorySizeForSetting(uint8_t SettingNumber);
+uint32_t AppWorkingMemorySizeForSetting(uint8_t SettingNumber);
+uint32_t AppMemorySizeForSetting(uint8_t SettingNumber);
+uint32_t AppCardMemorySize(void);
+uint32_t AppWorkingMemorySize(void);
+uint32_t AppMemorySize(void);
+
+bool AppCardMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppCardMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppCardMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppWorkingMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppWorkingMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppWorkingMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount);
-bool AppMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount);
-bool AppMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount);
-bool AppMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppCardMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppCardMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppCardMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppWorkingMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppWorkingMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount);
+bool AppWorkingMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount);
bool MemoryClearAll(void);
bool AppMemoryClearForSetting(uint8_t SettingNumber);
bool AppMemoryClear(void);
+bool AppCardMemoryClearForSetting(uint8_t SettingNumber);
+bool AppCardMemoryClear(void);
+bool AppWorkingMemoryClearForSetting(uint8_t SettingNumber);
+bool AppWorkingMemoryClear(void);
#endif /* _MEM_MEMORY_H_ */
diff --git a/Firmware/ChameleonMini/Terminal/CommandLine.c b/Firmware/ChameleonMini/Terminal/CommandLine.c
index a95eebb..2078ebc 100644
--- a/Firmware/ChameleonMini/Terminal/CommandLine.c
+++ b/Firmware/ChameleonMini/Terminal/CommandLine.c
@@ -119,6 +119,27 @@ const PROGMEM CommandEntryType CommandTable[] = {
.SetFunc = NO_FUNCTION,
.GetFunc = CommandGetMemSize
},
+ {
+ .Command = COMMAND_WORKMEM,
+ .ExecFunc = CommandExecWorkingMem,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetWorkingMem
+ },
+ {
+ .Command = COMMAND_WORKMEMUPLOAD,
+ .ExecFunc = CommandExecWorkingMemUpload,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_WORKMEMDOWNLOAD,
+ .ExecFunc = CommandExecWorkingMemDownload,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
{
.Command = COMMAND_UIDSIZE,
.ExecFunc = NO_FUNCTION,
@@ -221,6 +242,7 @@ const PROGMEM CommandEntryType CommandTable[] = {
.SetFunc = NO_FUNCTION,
.GetFunc = CommandGetRssi
},
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
{
.Command = COMMAND_PWD,
.ExecFunc = NO_FUNCTION,
@@ -228,6 +250,7 @@ const PROGMEM CommandEntryType CommandTable[] = {
.SetFunc = NO_FUNCTION,
.GetFunc = CommandGetUltralightPassword
},
+#endif
/*
{
.Command = COMMAND_SYSTICK,
@@ -300,11 +323,11 @@ const PROGMEM CommandEntryType CommandTable[] = {
.GetFunc = CommandGetField
},
*/
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
{
.Command = COMMAND_DETECTION,
.ExecFunc = NO_FUNCTION,
- .SetFunc = CommandSetDetection,
+ .SetFunc = NO_FUNCTION,
.GetFunc = CommandGetDetection,
},
#endif
diff --git a/Firmware/ChameleonMini/Terminal/Commands.c b/Firmware/ChameleonMini/Terminal/Commands.c
index 4f7b5f6..b23e2da 100644
--- a/Firmware/ChameleonMini/Terminal/Commands.c
+++ b/Firmware/ChameleonMini/Terminal/Commands.c
@@ -217,12 +217,12 @@ CommandStatusIdType CommandSetReadOnly(char* OutMessage, const char* InParam)
}
CommandStatusIdType CommandExecUpload(char* OutMessage) {
- XModemReceive(AppMemoryUploadXModem);
+ XModemReceive(AppCardMemoryUploadXModem);
return COMMAND_INFO_XMODEM_WAIT_ID;
}
CommandStatusIdType CommandExecDownload(char* OutMessage) {
- XModemSend(AppMemoryDownloadXModem);
+ XModemSend(AppCardMemoryDownloadXModem);
return COMMAND_INFO_XMODEM_WAIT_ID;
}
@@ -243,10 +243,63 @@ CommandStatusIdType CommandExecUpgrade(char* OutMessage) {
#endif
CommandStatusIdType CommandGetMemSize(char* OutParam) {
- snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.MemorySize);
+ snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%lu"), ActiveConfiguration.CardMemorySize);
return COMMAND_INFO_OK_WITH_TEXT_ID;
}
+void _readAndSendWorkingMemChunk(uint32_t Address, uint16_t Size, uint16_t MaxSize, bool isHex) {
+ if((MaxSize <= TERMINAL_BUFFER_SIZE) && (Size <= MaxSize)) {
+ uint8_t buff[TERMINAL_BUFFER_SIZE];
+ AppWorkingMemoryRead(buff, Address, Size);
+ if(isHex) {
+ char hexbuff[TERMINAL_BUFFER_SIZE*2+3];
+ uint16_t zeroIndex = Size*2;
+ BufferToHexString(hexbuff, TERMINAL_BUFFER_SIZE*2+3, buff, Size);
+ hexbuff[zeroIndex] = '\r';
+ hexbuff[zeroIndex+1] = '\n';
+ hexbuff[zeroIndex+2] = '\0';
+ TerminalSendString(hexbuff);
+ } else {
+ TerminalSendBlock(buff, Size);
+ }
+ }
+}
+
+uint8_t _readAndSendWorkingMem(uint16_t MaxSize, bool isHex) {
+ uint8_t ret = COMMAND_ERR_INVALID_USAGE_ID;
+ uint32_t bytesToWrite = AppWorkingMemorySize();
+ if( (MaxSize <= TERMINAL_BUFFER_SIZE) && bytesToWrite ) {
+ uint32_t rounds = bytesToWrite / MaxSize;
+ uint16_t offset = bytesToWrite % MaxSize;
+ for(uint32_t i=0; i < rounds; i++) {
+ _readAndSendWorkingMemChunk(i*MaxSize, MaxSize, MaxSize, isHex);
+ }
+ if(offset) {
+ _readAndSendWorkingMemChunk(rounds*MaxSize, offset, MaxSize, isHex);
+ }
+ ret = (isHex) ? (COMMAND_INFO_OK_WITH_TEXT_ID) : (COMMAND_INFO_OK_ID);
+ }
+ return ret;
+}
+
+CommandStatusIdType CommandGetWorkingMem(char* OutParam) {
+ return _readAndSendWorkingMem(16, true);
+}
+
+CommandStatusIdType CommandExecWorkingMem(char* OutMessage) {
+ return _readAndSendWorkingMem(TERMINAL_BUFFER_SIZE, false);
+}
+
+CommandStatusIdType CommandExecWorkingMemUpload(char* OutMessage) {
+ XModemReceive(AppWorkingMemoryUploadXModem);
+ return COMMAND_INFO_XMODEM_WAIT_ID;
+}
+
+CommandStatusIdType CommandExecWorkingMemDownload(char* OutMessage) {
+ XModemSend(AppWorkingMemoryDownloadXModem);
+ return COMMAND_INFO_XMODEM_WAIT_ID;
+}
+
CommandStatusIdType CommandGetUidSize(char* OutParam) {
snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.UidSize);
return COMMAND_INFO_OK_WITH_TEXT_ID;
@@ -349,20 +402,22 @@ CommandStatusIdType CommandGetRssi(char* OutParam) {
return COMMAND_INFO_OK_WITH_TEXT_ID;
}
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
CommandStatusIdType CommandGetUltralightPassword(char* OutParam) {
- uint8_t pwd[4];
+ uint8_t pwd[MIFARE_ULTRALIGHT_PWD_SIZE];
/* Read saved password from authentication */
- AppMemoryRead(pwd, MIFARE_ULTRALIGHT_PWD_ADDRESS, sizeof(pwd));
+ AppWorkingMemoryRead(pwd, MIFARE_ULTRALIGHT_PWD_ADDRESS, MIFARE_ULTRALIGHT_PWD_SIZE);
snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%02x%02x%02x%02x"), pwd[0], pwd[1], pwd[2], pwd[3]);
return COMMAND_INFO_OK_WITH_TEXT_ID;
}
+#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
CommandStatusIdType CommandGetDetection(char* OutParam) {
/* Read UID / s0-b0 */
- AppMemoryRead(OutParam, MFCLASSIC_MEM_S0B0_ADDRESS, DETECTION_MEM_BLOCK0_SIZE);
+ AppWorkingMemoryRead(OutParam, MFCLASSIC_MEM_S0B0_ADDRESS, DETECTION_MEM_BLOCK0_SIZE);
/* Read saved nonce data from authentication */
- AppMemoryRead(OutParam+DETECTION_MEM_BLOCK0_SIZE, DETECTION_MEM_DATA_START_ADDR, DETECTION_MEM_MFKEY_DATA_LEN);
+ AppWorkingMemoryRead(OutParam+DETECTION_MEM_BLOCK0_SIZE, DETECTION_MEM_DATA_START_ADDR, DETECTION_MEM_MFKEY_DATA_LEN);
/* Add file integrity to byte. This adds 2 bytes (209, 210) to DETECTION_MEM_APP_SIZE */
ISO14443AAppendCRCA(OutParam, DETECTION_MEM_APP_SIZE);
/* Send data + CRC */
@@ -372,11 +427,6 @@ CommandStatusIdType CommandGetDetection(char* OutParam) {
OutParam[0] = 0;
return COMMAND_INFO_OK_ID;
}
-
-CommandStatusIdType CommandSetDetection(char* OutMessage, const char* InParam) {
- AppMemoryClear();
- return COMMAND_INFO_OK_ID;
-}
#endif
CommandStatusIdType CommandExecClearAll(char* OutMessage) {
@@ -387,7 +437,7 @@ CommandStatusIdType CommandExecClearAll(char* OutMessage) {
ButtonSetActionById(BUTTON_PRESS_SHORT, DEFAULT_BUTTON_ACTION);
ButtonSetActionById(BUTTON_PRESS_LONG, DEFAULT_BUTTON_LONG_ACTION);
}
- SettingsSetActiveById(SETTINGS_FIRST);
+ SettingsSetActiveById(DEFAULT_SETTING);
SettingsSave();
return COMMAND_INFO_OK_ID;
}
@@ -395,8 +445,8 @@ CommandStatusIdType CommandExecClearAll(char* OutMessage) {
#ifdef CONFIG_DEBUG_MEMORYINFO_COMMAND
CommandStatusIdType CommandExecMemoryInfo(char* OutMessage) {
snprintf_P( OutMessage, TERMINAL_BUFFER_SIZE,
- PSTR("SPI Flash:\r\n- Bytes Per Setting: %lu\r\n- MDID Bytes: %02X%02X%02X%02X\r\n- Memory size: %u Mbits (%u KBytes)\r\nEEPROM:\r\n- Bytes Per Setting: %u\r\n- Memory size: %u Bytes"),
- MemoryMappingInfo.maxFlashBytesPerSlot,
+ PSTR("SPI Flash:\r\n- Bytes Per Setting: %lu\r\n- Bytes Per Card Memory: %lu\r\n- MDID Bytes: %02X%02X%02X%02X\r\n- Memory size: %u Mbits (%u KBytes)\r\nEEPROM:\r\n- Bytes Per Setting: %u\r\n- Memory size: %u Bytes"),
+ MemoryMappingInfo.maxFlashBytesPerSlot, MemoryMappingInfo.maxFlashBytesPerCardMemory,
FlashInfo.manufacturerId, FlashInfo.deviceId1, FlashInfo.deviceId2, FlashInfo.edi,
FlashInfo.geometry.sizeMbits, FlashInfo.geometry.sizeKbytes,
MemoryMappingInfo.maxEEPROMBytesPerSlot, EEPROMInfo.bytesTotal );
@@ -407,47 +457,75 @@ CommandStatusIdType CommandExecMemoryInfo(char* OutMessage) {
#ifdef CONFIG_DEBUG_MEMORYTEST_COMMAND
CommandStatusIdType CommandExecMemoryTest(char* OutMessage) {
uint8_t bigbuf[128];
- uint8_t readbuf[45];
- uint8_t expected[45];
- HexStringToBuffer(expected, 45, "11111111AA031111111111111111111100FFFFFFFFAA03FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF05");
+ uint8_t readbuf[50];
+ uint8_t expected[50];
+ bool retValFail = false;
+ bool retValOK = false;
+ bool tempRetVal = false;
+ HexStringToBuffer(expected, 50,
+ "000111FFAA031111111111111111111100FFFFFFFFFF03FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF05111111AA02");
memset(bigbuf, 0x11, 128);
- memset(readbuf, 0xAA, 45);
+ memset(readbuf, 0xAA, 50);
SettingsSetActiveById(3);
- ConfigurationSetById(CONFIG_NONE);
+ ConfigurationSetById(CONFIG_MF_CLASSIC_1K);
+ SettingsSave();
+ SettingsSetActiveById(2);
+ ConfigurationSetById(CONFIG_MF_CLASSIC_DETECTION);
SettingsSave();
SettingsSetActiveById(0);
ConfigurationSetById(CONFIG_MF_CLASSIC_4K);
SettingsSave();
- AppMemoryWriteForSetting(3, bigbuf, 0, 512);
+ tempRetVal = AppCardMemoryWriteForSetting(3, bigbuf, 0, 128);
+ retValOK = tempRetVal;
for(uint8_t i = 0; i < 32; i++){
- AppMemoryWrite(bigbuf, i*128, 128);
+ tempRetVal = AppCardMemoryWrite(bigbuf, i*128, 128);
+ retValOK = (retValOK && tempRetVal);
}
- FlashUnbufferedBytesRead(readbuf, 3*MemoryMappingInfo.maxFlashBytesPerSlot, 4);
- AppMemoryReadForSetting(3, readbuf+4, 250, 1);
+ tempRetVal = FlashUnbufferedBytesRead(readbuf+2, 3*MemoryMappingInfo.maxFlashBytesPerSlot, 1);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = AppCardMemoryReadForSetting(3, readbuf+3, 128, 1);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = AppCardMemoryReadForSetting(3, readbuf, MFCLASSIC_1K_MEM_SIZE, 4);
+ retValFail = tempRetVal;
+ tempRetVal = AppWorkingMemoryReadForSetting(3, readbuf, 0, 1);
+ retValFail = (retValFail || tempRetVal);
readbuf[5] = 0x03;
- FlashUnbufferedBytesRead(readbuf+6, 1024, 1);
- FlashUnbufferedBytesRead(readbuf+7, 3118, 2);
- AppMemoryRead(readbuf+9, 2046, 3);
- AppMemoryRead(readbuf+12, 12, 4);
+ tempRetVal = FlashUnbufferedBytesRead(readbuf+6, 1024, 1);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = FlashUnbufferedBytesRead(readbuf+7, 3118, 2);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = AppCardMemoryRead(readbuf+9, 2046, 3);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = AppCardMemoryRead(readbuf+12, 12, 4);
+ retValOK = (retValOK && tempRetVal);
readbuf[16] = 0x00;
- FlashClearRange(3*MemoryMappingInfo.maxFlashBytesPerSlot, 16);
- AppMemoryClear();
+ tempRetVal = FlashClearRange(3*MemoryMappingInfo.maxFlashBytesPerSlot, 16);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = AppMemoryClear();
+ retValOK = (retValOK && tempRetVal);
FlashUnbufferedBytesRead(readbuf+17, 3*MemoryMappingInfo.maxFlashBytesPerSlot, 4);
- AppMemoryReadForSetting(3, readbuf+21, 250, 1);
+ AppCardMemoryReadForSetting(3, readbuf+21, 128, 1);
readbuf[22] = 0x03;
FlashUnbufferedBytesRead(readbuf+23, 1024, 1);
FlashUnbufferedBytesRead(readbuf+24, 3118, 2);
- AppMemoryRead(readbuf+26, 2046, 3);
- AppMemoryRead(readbuf+29, 12, 4);
+ AppCardMemoryRead(readbuf+26, 2046, 3);
+ AppCardMemoryRead(readbuf+29, 12, 4);
readbuf[33] = 0x00;
FlashUnbufferedBytesRead(readbuf+34, 5*MemoryMappingInfo.maxFlashBytesPerSlot+11, 10);
readbuf[44] = 0x05;
- FlashClearAll();
+ tempRetVal = AppWorkingMemoryWriteForSetting(2, bigbuf, 0, 16);
+ retValOK = (retValOK && tempRetVal);
+ tempRetVal = AppWorkingMemoryReadForSetting(2, readbuf+45, 5, 3);
+ retValOK = (retValOK && tempRetVal);
+ readbuf[49] = 0x02;
+ readbuf[0] = retValFail;
+ readbuf[1] = retValOK;
+ MemoryClearAll();
- if(memcmp(readbuf, expected, 45)) {
- BufferToHexString(OutMessage, TERMINAL_BUFFER_SIZE, readbuf, 45);
+ if(memcmp(readbuf, expected, 50)) {
+ BufferToHexString(OutMessage, TERMINAL_BUFFER_SIZE, readbuf, 50);
} else {
snprintf_P(OutMessage, TERMINAL_BUFFER_SIZE, PSTR("FINE"), NULL);
}
diff --git a/Firmware/ChameleonMini/Terminal/Commands.h b/Firmware/ChameleonMini/Terminal/Commands.h
index 8320e8c..b39285f 100644
--- a/Firmware/ChameleonMini/Terminal/Commands.h
+++ b/Firmware/ChameleonMini/Terminal/Commands.h
@@ -1,4 +1,4 @@
-/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL
+/* Copyright 2013 Timo Kasper, Simon KŸppers, David Oswald ("ORIGINAL
* AUTHORS"). All rights reserved.
*
* DEFINITIONS:
@@ -110,95 +110,106 @@ typedef struct {
CommandGetFuncType GetFunc;
} CommandEntryType;
-#define COMMAND_VERSION "VERSION"
+#define COMMAND_VERSION "VERSION"
CommandStatusIdType CommandGetVersion(char* OutParam);
-#define COMMAND_CONFIG "CONFIG"
+#define COMMAND_CONFIG "CONFIG"
CommandStatusIdType CommandExecConfig(char* OutMessage);
CommandStatusIdType CommandGetConfig(char* OutParam);
CommandStatusIdType CommandSetConfig(char* OutMessage, const char* InParam);
-#define COMMAND_UID "UID"
-#define COMMAND_UID_RANDOM "RANDOM"
+#define COMMAND_UID "UID"
+#define COMMAND_UID_RANDOM "RANDOM"
CommandStatusIdType CommandGetUid(char* OutParam);
CommandStatusIdType CommandSetUid(char* OutMessage, const char* InParam);
-#define COMMAND_ATQA "ATQA"
+#define COMMAND_ATQA "ATQA"
CommandStatusIdType CommandGetAtqa(char* OutParam);
CommandStatusIdType CommandSetAtqa(char* OutMessage, const char* InParam);
-#define COMMAND_SAK "SAK"
+#define COMMAND_SAK "SAK"
CommandStatusIdType CommandGetSak(char* OutParam);
CommandStatusIdType CommandSetSak(char* OutMessage, const char* InParam);
-#define COMMAND_READONLY "READONLY"
+#define COMMAND_READONLY "READONLY"
CommandStatusIdType CommandGetReadOnly(char* OutParam);
CommandStatusIdType CommandSetReadOnly(char* OutMessage, const char* InParam);
-#define COMMAND_UPLOAD "UPLOAD"
+#define COMMAND_UPLOAD "UPLOAD"
CommandStatusIdType CommandExecUpload(char* OutMessage);
-#define COMMAND_DOWNLOAD "DOWNLOAD"
+#define COMMAND_DOWNLOAD "DOWNLOAD"
CommandStatusIdType CommandExecDownload(char* OutMessage);
-#define COMMAND_RESET "RESET"
+#define COMMAND_RESET "RESET"
CommandStatusIdType CommandExecReset(char* OutMessage);
-#define COMMAND_UPGRADE "UPGRADE"
+#define COMMAND_UPGRADE "UPGRADE"
CommandStatusIdType CommandExecUpgrade(char* OutMessage);
-#define COMMAND_MEMSIZE "MEMSIZE"
+#define COMMAND_MEMSIZE "MEMSIZE"
CommandStatusIdType CommandGetMemSize(char* OutParam);
-#define COMMAND_UIDSIZE "UIDSIZE"
+#define COMMAND_WORKMEM "WORKMEM"
+CommandStatusIdType CommandGetWorkingMem(char* OutParam);
+CommandStatusIdType CommandExecWorkingMem(char* OutMessage);
+
+#define COMMAND_WORKMEMUPLOAD "WORKMEMUPLOAD"
+CommandStatusIdType CommandExecWorkingMemUpload(char* OutMessage);
+
+#define COMMAND_WORKMEMDOWNLOAD "WORKMEMDOWNLOAD"
+CommandStatusIdType CommandExecWorkingMemDownload(char* OutMessage);
+
+#define COMMAND_UIDSIZE "UIDSIZE"
CommandStatusIdType CommandGetUidSize(char* OutParam);
-#define COMMAND_BUTTON "BUTTON"
+#define COMMAND_BUTTON "BUTTON"
CommandStatusIdType CommandExecButton(char* OutMessage);
CommandStatusIdType CommandGetButton(char* OutParam);
CommandStatusIdType CommandSetButton(char* OutMessage, const char* InParam);
-#define COMMAND_BUTTON_LONG "BUTTON_LONG"
+#define COMMAND_BUTTON_LONG "BUTTON_LONG"
CommandStatusIdType CommandExecButtonLong(char* OutMessage);
CommandStatusIdType CommandGetButtonLong(char* OutParam);
CommandStatusIdType CommandSetButtonLong(char* OutMessage, const char* InParam);
-#define COMMAND_SETTING "SETTING"
+#define COMMAND_SETTING "SETTING"
CommandStatusIdType CommandGetSetting(char* OutParam);
CommandStatusIdType CommandSetSetting(char* OutMessage, const char* InParam);
-#define COMMAND_CLEAR "CLEAR"
+#define COMMAND_CLEAR "CLEAR"
CommandStatusIdType CommandExecClear(char* OutParam);
-#define COMMAND_HELP "HELP"
+#define COMMAND_HELP "HELP"
CommandStatusIdType CommandExecHelp(char* OutMessage);
-#define COMMAND_RSSI "RSSI"
+#define COMMAND_RSSI "RSSI"
CommandStatusIdType CommandGetRssi(char* OutParam);
-#define COMMAND_PWD "PWD"
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+#define COMMAND_PWD "PWD"
CommandStatusIdType CommandGetUltralightPassword(char* OutParam);
+#endif
-#ifdef CONFIG_MF_DETECTION_SUPPORT
-#define COMMAND_DETECTION "DETECTION"
+#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT
+#define COMMAND_DETECTION "DETECTION"
CommandStatusIdType CommandGetDetection(char* OutParam);
-CommandStatusIdType CommandSetDetection(char* OutMessage, const char* InParam);
#endif
-#define COMMAND_CLEARALL "CLEARALL"
+#define COMMAND_CLEARALL "CLEARALL"
CommandStatusIdType CommandExecClearAll(char* OutMessage);
#ifdef CONFIG_DEBUG_MEMORYINFO_COMMAND
-#define COMMAND_MEMORYINFO "MEMORYINFO"
+#define COMMAND_MEMORYINFO "MEMORYINFO"
CommandStatusIdType CommandExecMemoryInfo(char* OutMessage);
#endif
#ifdef CONFIG_DEBUG_MEMORYTEST_COMMAND
-#define COMMAND_MEMORYTEST "MEMORYTEST"
+#define COMMAND_MEMORYTEST "MEMORYTEST"
CommandStatusIdType CommandExecMemoryTest(char* OutMessage);
#endif
-#define COMMAND_LIST_END ""
+#define COMMAND_LIST_END ""
/* Defines the end of command list. This is no actual command */