]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/BigBuf.c
Merge pull request #250 from pwpiwi/fix_mfkey
[proxmark3-svn] / armsrc / BigBuf.c
CommitLineData
117d9ec2 1//-----------------------------------------------------------------------------
2// Jonathan Westhues, Aug 2005
3// Gerhard de Koning Gans, April 2008, May 2011
4//
5// This code is licensed to you under the terms of the GNU GPL, version 2 or,
6// at your option, any later version. See the LICENSE.txt file for the text of
7// the license.
8//-----------------------------------------------------------------------------
9// BigBuf and functions to allocate/free parts of it.
10//-----------------------------------------------------------------------------
11
12#include <stdint.h>
13#include "proxmark3.h"
14#include "apps.h"
15#include "string.h"
b8e461ff 16#include "util.h"
117d9ec2 17
f71f4deb 18// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
19// Also used to hold various smaller buffers and the Mifare Emulator Memory.
20
21// declare it as uint32_t to achieve alignment to 4 Byte boundary
22static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
117d9ec2 23
24// High memory mark
25static uint16_t BigBuf_hi = BIGBUF_SIZE;
26
f71f4deb 27// pointer to the emulator memory.
28static uint8_t *emulator_memory = NULL;
29
3000dc4e
MHS
30// trace related variables
31static uint16_t traceLen = 0;
32int tracing = 1; //Last global one.. todo static?
117d9ec2 33
34// get the address of BigBuf
35uint8_t *BigBuf_get_addr(void)
36{
f71f4deb 37 return (uint8_t *)BigBuf;
38}
39
40
41// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
42uint8_t *BigBuf_get_EM_addr(void)
43{
44 if (emulator_memory == NULL) { // not yet allocated
45 emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
46 }
47
48 return emulator_memory;
117d9ec2 49}
50
51
52// clear ALL of BigBuf
53void BigBuf_Clear(void)
7cfc777b 54{
55 BigBuf_Clear_ext(true);
56}
57// clear ALL of BigBuf
58void BigBuf_Clear_ext(bool verbose)
117d9ec2 59{
60 memset(BigBuf,0,BIGBUF_SIZE);
7cfc777b 61 if (verbose)
62 Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
117d9ec2 63}
64
3cec7061 65void BigBuf_Clear_keep_EM(void)
66{
67 memset(BigBuf,0,BigBuf_hi);
68}
117d9ec2 69
f71f4deb 70// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
71// at the beginning of BigBuf is always for traces/samples
117d9ec2 72uint8_t *BigBuf_malloc(uint16_t chunksize)
73{
74 if (BigBuf_hi - chunksize < 0) {
f71f4deb 75 return NULL; // no memory left
117d9ec2 76 } else {
f71f4deb 77 chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
78 BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
79 return (uint8_t *)BigBuf + BigBuf_hi;
117d9ec2 80 }
81}
82
83
f71f4deb 84// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
117d9ec2 85void BigBuf_free(void)
86{
87 BigBuf_hi = BIGBUF_SIZE;
f71f4deb 88 emulator_memory = NULL;
89}
90
91
92// free allocated chunks EXCEPT the emulator memory
93void BigBuf_free_keep_EM(void)
94{
95 if (emulator_memory != NULL) {
96 BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
97 } else {
98 BigBuf_hi = BIGBUF_SIZE;
99 }
117d9ec2 100}
101
e2012d1b
MHS
102void BigBuf_print_status(void)
103{
104 Dbprintf("Memory");
105 Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
106 Dbprintf(" BigBuf_hi .............%d", BigBuf_hi);
107 Dbprintf("Tracing");
108 Dbprintf(" tracing ................%d", tracing);
109 Dbprintf(" traceLen ...............%d", traceLen);
110}
111
117d9ec2 112
113// return the maximum trace length (i.e. the unallocated size of BigBuf)
f71f4deb 114uint16_t BigBuf_max_traceLen(void)
117d9ec2 115{
116 return BigBuf_hi;
f71f4deb 117}
3000dc4e
MHS
118
119void clear_trace() {
3000dc4e
MHS
120 traceLen = 0;
121}
122
123void set_tracing(bool enable) {
124 tracing = enable;
125}
126
127/**
128 * Get the number of bytes traced
129 * @return
130 */
131uint16_t BigBuf_get_traceLen(void)
132{
133 return traceLen;
134}
135
136/**
137 This is a function to store traces. All protocols can use this generic tracer-function.
138 The traces produced by calling this function can be fetched on the client-side
139 by 'hf list raw', alternatively 'hf list <proto>' for protocol-specific
140 annotation of commands/responses.
141
142**/
143bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
144{
145 if (!tracing) return FALSE;
146
147 uint8_t *trace = BigBuf_get_addr();
148
149 uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
150 uint16_t duration = timestamp_end - timestamp_start;
151
152 // Return when trace is full
153 uint16_t max_traceLen = BigBuf_max_traceLen();
154
155 if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
156 tracing = FALSE; // don't trace any more
157 return FALSE;
158 }
159 // Traceformat:
160 // 32 bits timestamp (little endian)
161 // 16 bits duration (little endian)
162 // 16 bits data length (little endian, Highest Bit used as readerToTag flag)
163 // y Bytes data
164 // x Bytes parity (one byte per 8 bytes data)
165
166 // timestamp (start)
167 trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
168 trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
169 trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
170 trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
171
172 // duration
173 trace[traceLen++] = ((duration >> 0) & 0xff);
174 trace[traceLen++] = ((duration >> 8) & 0xff);
175
176 // data length
177 trace[traceLen++] = ((iLen >> 0) & 0xff);
178 trace[traceLen++] = ((iLen >> 8) & 0xff);
179
180 // readerToTag flag
181 if (!readerToTag) {
182 trace[traceLen - 1] |= 0x80;
183 }
184
185 // data bytes
186 if (btBytes != NULL && iLen != 0) {
187 memcpy(trace + traceLen, btBytes, iLen);
188 }
189 traceLen += iLen;
190
191 // parity bytes
c4c3af7c 192 if (num_paritybytes != 0) {
48ece4a7 193 if (parity != NULL) {
194 memcpy(trace + traceLen, parity, num_paritybytes);
195 } else {
196 memset(trace + traceLen, 0x00, num_paritybytes);
197 }
3000dc4e
MHS
198 }
199 traceLen += num_paritybytes;
200
3000dc4e
MHS
201 return TRUE;
202}
09ffd16e 203
204
beefe5bc 205int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
aabb719d 206{
beefe5bc
MHS
207 /**
208 Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
209 that this logger takes number of bits as argument, not number of bytes.
210 **/
aabb719d 211
665775c8
MHS
212 if (!tracing) return FALSE;
213
214 uint8_t *trace = BigBuf_get_addr();
215 uint16_t iLen = nbytes(iBits);
aabb719d 216 // Return when trace is full
665775c8
MHS
217 if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return FALSE;
218
219 //Hitag traces appear to use this traceformat:
220 // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
221 // 32 bits parity
beefe5bc 222 // 8 bits size (number of bits in the trace entry, not number of bytes)
665775c8 223 // y Bytes data
aabb719d 224
aabb719d
MHS
225 rsamples += iSamples;
226 trace[traceLen++] = ((rsamples >> 0) & 0xff);
227 trace[traceLen++] = ((rsamples >> 8) & 0xff);
228 trace[traceLen++] = ((rsamples >> 16) & 0xff);
229 trace[traceLen++] = ((rsamples >> 24) & 0xff);
665775c8 230
beefe5bc 231 if (!readerToTag) {
665775c8 232 trace[traceLen - 1] |= 0x80;
aabb719d 233 }
665775c8 234
aabb719d
MHS
235 trace[traceLen++] = ((dwParity >> 0) & 0xff);
236 trace[traceLen++] = ((dwParity >> 8) & 0xff);
237 trace[traceLen++] = ((dwParity >> 16) & 0xff);
238 trace[traceLen++] = ((dwParity >> 24) & 0xff);
239 trace[traceLen++] = iBits;
665775c8
MHS
240
241 memcpy(trace + traceLen, btBytes, iLen);
242 traceLen += iLen;
243
aabb719d
MHS
244 return TRUE;
245}
48ece4a7 246
247
e80aeb96
MHS
248// Emulator memory
249uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
250 uint8_t* mem = BigBuf_get_EM_addr();
251 if(offset+length < CARD_MEMORY_SIZE)
252 {
253 memcpy(mem+offset, data, length);
254 return 0;
255 }else
256 {
257 Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset+length), CARD_MEMORY_SIZE);
258 return 1;
259 }
260}
Impressum, Datenschutz