]> cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/BigBuf.c
1b5e54823709771888848f1b59cb4b25a96f8a45
[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
20 // declare it as uint32_t to achieve alignment to 4 Byte boundary
21 static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
22
23 // High memory mark
24 static uint16_t BigBuf_hi = BIGBUF_SIZE;
25
26 // pointer to the emulator memory.
27 static uint8_t *emulator_memory = NULL;
28
29 // trace related variables
30 static uint16_t traceLen = 0;
31 int tracing = 1; //Last global one.. todo static?
32
33 // get the address of BigBuf
34 uint8_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
41 uint8_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
52 void 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
61 uint8_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.
74 void BigBuf_free(void)
75 {
76 BigBuf_hi = BIGBUF_SIZE;
77 emulator_memory = NULL;
78 }
79
80
81 // free allocated chunks EXCEPT the emulator memory
82 void 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)
93 uint16_t BigBuf_max_traceLen(void)
94 {
95 return BigBuf_hi;
96 }
97
98 void 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
105 void set_tracing(bool enable) {
106 tracing = enable;
107 }
108
109 /**
110 * Get the number of bytes traced
111 * @return
112 */
113 uint16_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 **/
125 bool 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
174 if (parity != NULL && iLen != 0) {
175 memcpy(trace + traceLen, parity, num_paritybytes);
176 }
177 traceLen += num_paritybytes;
178
179 if(traceLen +4 < max_traceLen)
180 { //If it hadn't been cleared, for whatever reason..
181 memset(trace+traceLen,0x44, 4);
182 }
183
184 return TRUE;
185 }
Impressum, Datenschutz