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