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