]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/BigBuf.c
FIX: changed from ssized_t -> size_t
[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.
f71f4deb 19// declare it as uint32_t to achieve alignment to 4 Byte boundary
20static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
117d9ec2 21
aaa1a9a2 22/* BigBuf memory layout:
23Pointer 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
117d9ec2 30// High memory mark
31static uint16_t BigBuf_hi = BIGBUF_SIZE;
32
f71f4deb 33// pointer to the emulator memory.
34static uint8_t *emulator_memory = NULL;
35
3000dc4e 36// trace related variables
c0f15a05 37static uint16_t traceLen = 0;
3000dc4e 38int tracing = 1; //Last global one.. todo static?
117d9ec2 39
40// get the address of BigBuf
41uint8_t *BigBuf_get_addr(void)
42{
f71f4deb 43 return (uint8_t *)BigBuf;
44}
45
f71f4deb 46// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
47uint8_t *BigBuf_get_EM_addr(void)
48{
aaa1a9a2 49 // not yet allocated
50 if (emulator_memory == NULL)
f71f4deb 51 emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
f71f4deb 52
53 return emulator_memory;
117d9ec2 54}
55
117d9ec2 56// clear ALL of BigBuf
57void BigBuf_Clear(void)
a739812e 58{
59 BigBuf_Clear_ext(true);
60}
6fc68747 61
a739812e 62// clear ALL of BigBuf
63void BigBuf_Clear_ext(bool verbose)
117d9ec2 64{
aaa1a9a2 65 memset(BigBuf, 0, BIGBUF_SIZE);
a739812e 66 if (verbose)
5bb62283 67 Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
117d9ec2 68}
69
c0f15a05 70void BigBuf_Clear_keep_EM(void)
71{
aaa1a9a2 72 memset(BigBuf, 0, BigBuf_hi);
c0f15a05 73}
117d9ec2 74
f71f4deb 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
117d9ec2 77uint8_t *BigBuf_malloc(uint16_t chunksize)
78{
79 if (BigBuf_hi - chunksize < 0) {
f71f4deb 80 return NULL; // no memory left
117d9ec2 81 } else {
f71f4deb 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;
117d9ec2 85 }
86}
87
f71f4deb 88// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
117d9ec2 89void BigBuf_free(void)
90{
91 BigBuf_hi = BIGBUF_SIZE;
f71f4deb 92 emulator_memory = NULL;
aaa1a9a2 93
94 // shouldn't this empty BigBuf also?
f71f4deb 95}
96
f71f4deb 97// free allocated chunks EXCEPT the emulator memory
98void BigBuf_free_keep_EM(void)
99{
aaa1a9a2 100 if (emulator_memory != NULL)
f71f4deb 101 BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
aaa1a9a2 102 else
f71f4deb 103 BigBuf_hi = BIGBUF_SIZE;
aaa1a9a2 104
105 // shouldn't this empty BigBuf also?
117d9ec2 106}
107
7838f4be 108void BigBuf_print_status(void)
109{
110 Dbprintf("Memory");
111 Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
aaa1a9a2 112 Dbprintf(" Available memory........%d", BigBuf_hi);
7838f4be 113 Dbprintf("Tracing");
114 Dbprintf(" tracing ................%d", tracing);
115 Dbprintf(" traceLen ...............%d", traceLen);
116}
117
117d9ec2 118// return the maximum trace length (i.e. the unallocated size of BigBuf)
f71f4deb 119uint16_t BigBuf_max_traceLen(void)
117d9ec2 120{
121 return BigBuf_hi;
f71f4deb 122}
3000dc4e
MHS
123
124void clear_trace() {
3000dc4e
MHS
125 traceLen = 0;
126}
127
128void set_tracing(bool enable) {
129 tracing = enable;
130}
131
132/**
133 * Get the number of bytes traced
134 * @return
135 */
136uint16_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**/
148bool 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
aaa1a9a2 158 if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) {
3000dc4e
MHS
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
7f6ccd39 195 if (num_paritybytes != 0) {
7838f4be 196 if (parity != NULL) {
664bb5ae 197 memcpy(trace + traceLen, parity, num_paritybytes);
7838f4be 198 } else {
199 memset(trace + traceLen, 0x00, num_paritybytes);
200 }
3000dc4e
MHS
201 }
202 traceLen += num_paritybytes;
203
3000dc4e
MHS
204 return TRUE;
205}
0ec548dc 206
207
beefe5bc 208int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
aabb719d 209{
beefe5bc
MHS
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 **/
aabb719d 214
665775c8
MHS
215 if (!tracing) return FALSE;
216
217 uint8_t *trace = BigBuf_get_addr();
218 uint16_t iLen = nbytes(iBits);
aabb719d 219 // Return when trace is full
665775c8
MHS
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
beefe5bc 225 // 8 bits size (number of bits in the trace entry, not number of bytes)
665775c8 226 // y Bytes data
aabb719d 227
aabb719d
MHS
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);
665775c8 233
beefe5bc 234 if (!readerToTag) {
665775c8 235 trace[traceLen - 1] |= 0x80;
aabb719d 236 }
665775c8 237
aabb719d
MHS
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;
665775c8
MHS
243
244 memcpy(trace + traceLen, btBytes, iLen);
245 traceLen += iLen;
246
aabb719d
MHS
247 return TRUE;
248}
7838f4be 249
c0f15a05 250
e80aeb96
MHS
251// Emulator memory
252uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
253 uint8_t* mem = BigBuf_get_EM_addr();
6fc68747 254 if(offset+length < CARD_MEMORY_SIZE) {
e80aeb96
MHS
255 memcpy(mem+offset, data, length);
256 return 0;
6fc68747 257 } else {
e80aeb96
MHS
258 Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset+length), CARD_MEMORY_SIZE);
259 return 1;
260 }
261}
Impressum, Datenschutz