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