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