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