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