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