This repository has been archived by the owner on Mar 16, 2022. It is now read-only.
/
DESFireMemoryOperations.c
138 lines (119 loc) · 4.76 KB
/
DESFireMemoryOperations.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
The DESFire stack portion of this firmware source
is free software written by Maxie Dion Schmidt (@maxieds):
You can redistribute it and/or modify
it under the terms of this license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The complete source distribution of
this firmware is available at the following link:
https://github.com/maxieds/ChameleonMiniFirmwareDESFireStack.
Based in part on the original DESFire code created by
@dev-zzo (GitHub handle) [Dmitry Janushkevich] available at
https://github.com/dev-zzo/ChameleonMini/tree/desfire.
This notice must be retained at the top of all source files where indicated.
*/
/*
* DESFireMemoryOperations.c
* Maxie D. Schmidt (github.com/maxieds)
*/
#ifdef CONFIG_MF_DESFIRE_SUPPORT
#include "../../Memory.h"
#include "DESFireMemoryOperations.h"
#include "DESFirePICCControl.h"
#include "DESFireFile.h"
#include "DESFireLogging.h"
volatile char __InternalStringBuffer[STRING_BUFFER_SIZE] = { 0 };
char __InternalStringBuffer2[DATA_BUFFER_SIZE_SMALL] = { 0 };
void ReadBlockBytes(void* Buffer, SIZET StartBlock, SIZET Count) {
if(StartBlock * DESFIRE_EEPROM_BLOCK_SIZE >= MEMORY_SIZE_PER_SETTING) {
const char *rbbLogMsg = PSTR("RBB Start Block Too Large -- %d -- %d");
DEBUG_PRINT_P(rbbLogMsg, StartBlock, StartBlock * DESFIRE_EEPROM_BLOCK_SIZE);
return;
}
//else if(StartBlock == 0) {
// const char *logWarningMsg = PSTR("WARNING: Reading NULL Address!");
// DEBUG_PRINT_P(logWarningMsg);
//}
MemoryReadBlockInSetting(Buffer, StartBlock * DESFIRE_EEPROM_BLOCK_SIZE, Count);
}
void WriteBlockBytesMain(const void* Buffer, SIZET StartBlock, SIZET Count) {
if(StartBlock * DESFIRE_EEPROM_BLOCK_SIZE >= MEMORY_SIZE_PER_SETTING) {
const char *wbbLogMsg = PSTR("WBB Start Block Too Large -- %d -- %s");
DEBUG_PRINT_P(wbbLogMsg, StartBlock, __InternalStringBuffer2);
return;
}
//else if(StartBlock == 0) {
// const char *logWarningMsg = PSTR("WARNING: Writing NULL! -- %s");
// DEBUG_PRINT_P(logWarningMsg, __InternalStringBuffer2);
//}
MemoryWriteBlockInSetting(Buffer, StartBlock * DESFIRE_EEPROM_BLOCK_SIZE, Count);
}
void CopyBlockBytes(SIZET DestBlock, SIZET SrcBlock, SIZET Count) {
uint8_t Buffer[DESFIRE_EEPROM_BLOCK_SIZE];
uint16_t SrcOffset = SrcBlock;
uint16_t DestOffset = DestBlock;
while(Count > 0) {
SIZET bytesToWrite = MIN(Count, DESFIRE_EEPROM_BLOCK_SIZE);
ReadBlockBytes(Buffer, SrcOffset, bytesToWrite);
WriteBlockBytes(Buffer, DestOffset, bytesToWrite);
SrcOffset += 1;
DestOffset += 1;
Count -= DESFIRE_EEPROM_BLOCK_SIZE;
}
}
uint16_t AllocateBlocksMain(uint16_t BlockCount) {
uint16_t Block;
/* Check if we have space */
Block = Picc.FirstFreeBlock;
if(Block + BlockCount < Block || Block + BlockCount >= MEMORY_SIZE_PER_SETTING / DESFIRE_EEPROM_BLOCK_SIZE) {
return 0;
}
Picc.FirstFreeBlock = Block + BlockCount;
DESFIRE_INITIAL_FIRST_FREE_BLOCK_ID = Picc.FirstFreeBlock;
SynchronizePICCInfo();
return Block;
}
/* TODO: Why doesn't this work ??? -- It freezes the AVR chip when run !! */
void MemsetBlockBytes(uint8_t initValue, SIZET startBlock, SIZET byteCount) {
BYTE fillerBuf[DESFIRE_EEPROM_BLOCK_SIZE];
memset(fillerBuf, initValue, DESFIRE_EEPROM_BLOCK_SIZE);
SIZET writeAddr = startBlock;
while(byteCount > 0) {
WriteBlockBytes(&fillerBuf[0], writeAddr, MIN(DESFIRE_EEPROM_BLOCK_SIZE, byteCount));
++writeAddr;
if(byteCount > DESFIRE_EEPROM_BLOCK_SIZE) {
byteCount -= DESFIRE_EEPROM_BLOCK_SIZE;
}
else {
break;
}
}
}
uint8_t GetCardCapacityBlocks(void) {
uint8_t MaxFreeBlocks;
switch (Picc.StorageSize) {
case DESFIRE_STORAGE_SIZE_2K:
MaxFreeBlocks = 0x40 - DESFIRE_FIRST_FREE_BLOCK_ID;
break;
case DESFIRE_STORAGE_SIZE_4K:
MaxFreeBlocks = 0x80 - DESFIRE_FIRST_FREE_BLOCK_ID;
break;
case DESFIRE_STORAGE_SIZE_8K:
MaxFreeBlocks = (BYTE) (0x100 - DESFIRE_FIRST_FREE_BLOCK_ID);
break;
default:
return 0;
}
return MaxFreeBlocks - Picc.FirstFreeBlock;
}
void ReadDataEEPROMSource(uint8_t* Buffer, uint8_t Count) {
MemoryReadBlock(Buffer, TransferState.ReadData.Source.Pointer, Count);
TransferState.ReadData.Source.Pointer += DESFIRE_BYTES_TO_BLOCKS(Count);
}
void WriteDataEEPROMSink(uint8_t* Buffer, uint8_t Count) {
MemoryWriteBlock(Buffer, TransferState.WriteData.Sink.Pointer, Count);
TransferState.WriteData.Sink.Pointer += DESFIRE_BYTES_TO_BLOCKS(Count);
}
#endif /* CONFIG_MF_DESFIRE_SUPPORT */