]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/BigBuf.c
hf topaz reader implementation:
[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
e2012d1b
MHS
91void 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
117d9ec2 101
102// return the maximum trace length (i.e. the unallocated size of BigBuf)
f71f4deb 103uint16_t BigBuf_max_traceLen(void)
117d9ec2 104{
105 return BigBuf_hi;
f71f4deb 106}
3000dc4e
MHS
107
108void clear_trace() {
3000dc4e
MHS
109 traceLen = 0;
110}
111
112void set_tracing(bool enable) {
113 tracing = enable;
114}
115
116/**
117 * Get the number of bytes traced
118 * @return
119 */
120uint16_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**/
132bool 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
48ece4a7 181 if (iLen != 0) {
182 if (parity != NULL) {
183 memcpy(trace + traceLen, parity, num_paritybytes);
184 } else {
185 memset(trace + traceLen, 0x00, num_paritybytes);
186 }
3000dc4e
MHS
187 }
188 traceLen += num_paritybytes;
189
3000dc4e
MHS
190 return TRUE;
191}
48ece4a7 192
193
beefe5bc 194int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
aabb719d 195{
beefe5bc
MHS
196 /**
197 Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
198 that this logger takes number of bits as argument, not number of bytes.
199 **/
aabb719d 200
665775c8
MHS
201 if (!tracing) return FALSE;
202
203 uint8_t *trace = BigBuf_get_addr();
204 uint16_t iLen = nbytes(iBits);
aabb719d 205 // Return when trace is full
665775c8
MHS
206 if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return FALSE;
207
208 //Hitag traces appear to use this traceformat:
209 // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
210 // 32 bits parity
beefe5bc 211 // 8 bits size (number of bits in the trace entry, not number of bytes)
665775c8 212 // y Bytes data
aabb719d 213
aabb719d
MHS
214 rsamples += iSamples;
215 trace[traceLen++] = ((rsamples >> 0) & 0xff);
216 trace[traceLen++] = ((rsamples >> 8) & 0xff);
217 trace[traceLen++] = ((rsamples >> 16) & 0xff);
218 trace[traceLen++] = ((rsamples >> 24) & 0xff);
665775c8 219
beefe5bc 220 if (!readerToTag) {
665775c8 221 trace[traceLen - 1] |= 0x80;
aabb719d 222 }
665775c8 223
aabb719d
MHS
224 trace[traceLen++] = ((dwParity >> 0) & 0xff);
225 trace[traceLen++] = ((dwParity >> 8) & 0xff);
226 trace[traceLen++] = ((dwParity >> 16) & 0xff);
227 trace[traceLen++] = ((dwParity >> 24) & 0xff);
228 trace[traceLen++] = iBits;
665775c8
MHS
229
230 memcpy(trace + traceLen, btBytes, iLen);
231 traceLen += iLen;
232
aabb719d
MHS
233 return TRUE;
234}
48ece4a7 235
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