1
1
#include "mag_helpers.h"
2
+ #include "../mag_i.h"
2
3
3
4
#define GPIO_PIN_A &gpio_ext_pa6
4
5
#define GPIO_PIN_B &gpio_ext_pa7
7
8
#define ZERO_PREFIX 25 // n zeros prefix
8
9
#define ZERO_BETWEEN 53 // n zeros between tracks
9
10
#define ZERO_SUFFIX 25 // n zeros suffix
10
- #define US_CLOCK 240
11
- #define US_INTERPACKET 10
11
+ // #define US_CLOCK 240
12
+ // #define US_INTERPACKET 10
12
13
13
14
// bits per char on a given track
14
15
const uint8_t bitlen [] = {7 , 5 , 5 };
15
16
// char offset by track
16
17
const int sublen [] = {32 , 48 , 48 };
17
18
uint8_t bit_dir = 0 ;
18
19
19
- void play_bit_rfid (uint8_t send_bit ) {
20
+ void play_bit_rfid (uint8_t send_bit , MagSetting * setting ) {
20
21
// internal TX over RFID coil
21
22
bit_dir ^= 1 ;
22
23
furi_hal_gpio_write (RFID_PIN , bit_dir );
23
- furi_delay_us (US_CLOCK );
24
+ furi_delay_us (setting -> us_clock );
24
25
25
26
if (send_bit ) {
26
27
bit_dir ^= 1 ;
27
28
furi_hal_gpio_write (RFID_PIN , bit_dir );
28
29
}
29
- furi_delay_us (US_CLOCK );
30
+ furi_delay_us (setting -> us_clock );
30
31
31
- furi_delay_us (US_INTERPACKET );
32
+ furi_delay_us (setting -> us_interpacket );
32
33
}
33
34
34
- /*static void play_bit_gpio(uint8_t send_bit) {
35
+ void play_bit_gpio (uint8_t send_bit , MagSetting * setting ) {
35
36
// external TX over motor driver wired to PIN_A and PIN_B
36
37
bit_dir ^= 1 ;
37
38
furi_hal_gpio_write (GPIO_PIN_A , bit_dir );
38
39
furi_hal_gpio_write (GPIO_PIN_B , !bit_dir );
39
- furi_delay_us(US_CLOCK );
40
+ furi_delay_us (setting -> us_clock );
40
41
41
42
if (send_bit ) {
42
43
bit_dir ^= 1 ;
43
44
furi_hal_gpio_write (GPIO_PIN_A , bit_dir );
44
45
furi_hal_gpio_write (GPIO_PIN_B , !bit_dir );
45
46
}
46
- furi_delay_us(US_CLOCK );
47
+ furi_delay_us (setting -> us_clock );
47
48
48
- furi_delay_us(US_INTERPACKET);
49
- }*/
49
+ furi_delay_us (setting -> us_interpacket );
50
+ }
51
+
52
+ bool play_bit (uint8_t send_bit , MagSetting * setting ) {
53
+ // Initialize configured TX method
54
+ if (setting -> tx == MagTxStateRFID ) {
55
+ play_bit_rfid (send_bit , setting );
56
+ } else if (setting -> tx == MagTxStateGPIOA6A7 ) {
57
+ play_bit_gpio (send_bit , setting );
58
+ } else {
59
+ return false;
60
+ }
50
61
51
- void rfid_tx_init () {
62
+ return true;
63
+ }
64
+
65
+ void tx_init_rfid () {
52
66
// initialize RFID system for TX
53
67
furi_hal_power_enable_otg ();
54
68
@@ -73,29 +87,54 @@ void rfid_tx_init() {
73
87
furi_delay_ms (300 );
74
88
}
75
89
76
- void rfid_tx_reset () {
90
+ void tx_reset_rfid () {
77
91
// reset RFID system
78
92
furi_hal_gpio_write (RFID_PIN , 0 );
79
93
80
94
furi_hal_rfid_pins_reset ();
81
95
furi_hal_power_disable_otg ();
82
96
}
83
97
84
- /*
85
- static void gpio_tx_init() {
98
+ void tx_init_gpio () {
86
99
furi_hal_power_enable_otg ();
87
- gpio_item_configure_all_pins(GpioModeOutputPushPull);
100
+ // gpio_item_configure_all_pins(GpioModeOutputPushPull);
101
+ furi_hal_gpio_init (GPIO_PIN_A , GpioModeOutputPushPull , GpioPullNo , GpioSpeedLow );
102
+ furi_hal_gpio_init (GPIO_PIN_B , GpioModeOutputPushPull , GpioPullNo , GpioSpeedLow );
88
103
}
89
104
90
- static void gpio_tx_reset() {
91
- gpio_item_set_pin(PIN_A, 0);
92
- gpio_item_set_pin(PIN_B, 0);
93
- gpio_item_set_pin(ENABLE_PIN, 0);
105
+ void tx_reset_gpio () {
106
+ furi_hal_gpio_write (GPIO_PIN_A , 0 );
107
+ furi_hal_gpio_write (GPIO_PIN_B , 0 );
94
108
95
- gpio_item_configure_all_pins(GpioModeAnalog);
109
+ // gpio_item_configure_all_pins(GpioModeAnalog);
96
110
furi_hal_power_disable_otg ();
97
111
}
98
- */
112
+
113
+ bool tx_init (MagSetting * setting ) {
114
+ // Initialize configured TX method
115
+ if (setting -> tx == MagTxStateRFID ) {
116
+ tx_init_rfid ();
117
+ } else if (setting -> tx == MagTxStateGPIOA6A7 ) {
118
+ tx_init_gpio ();
119
+ } else {
120
+ return false;
121
+ }
122
+
123
+ return true;
124
+ }
125
+
126
+ bool tx_reset (MagSetting * setting ) {
127
+ // Reset configured TX method
128
+ if (setting -> tx == MagTxStateRFID ) {
129
+ tx_reset_rfid ();
130
+ } else if (setting -> tx == MagTxStateGPIOA6A7 ) {
131
+ tx_reset_gpio ();
132
+ } else {
133
+ return false;
134
+ }
135
+
136
+ return true;
137
+ }
99
138
100
139
void track_to_bits (uint8_t * bit_array , const char * track_data , uint8_t track_index ) {
101
140
// convert individual track to bits
@@ -139,10 +178,11 @@ void track_to_bits(uint8_t* bit_array, const char* track_data, uint8_t track_ind
139
178
//furi_assert(is_correct_length);
140
179
}
141
180
181
+ /*
142
182
void mag_spoof_single_track_rfid(FuriString* track_str, uint8_t track_index) {
143
183
// Quick testing...
144
184
145
- rfid_tx_init ();
185
+ tx_init_rfid ();
146
186
147
187
size_t from;
148
188
size_t to;
@@ -173,13 +213,13 @@ void mag_spoof_single_track_rfid(FuriString* track_str, uint8_t track_index) {
173
213
for(uint8_t i = 0; i < ZERO_SUFFIX; i++) play_bit_rfid(0);
174
214
FURI_CRITICAL_EXIT();
175
215
176
- rfid_tx_reset ();
216
+ tx_reset_rfid ();
177
217
}
178
218
179
219
void mag_spoof_two_track_rfid(FuriString* track1, FuriString* track2) {
180
220
// Quick testing...
181
221
182
- rfid_tx_init ();
222
+ tx_init_rfid ();
183
223
184
224
const char* data1 = furi_string_get_cstr(track1);
185
225
uint8_t bit_array1[(strlen(data1) * bitlen[0]) + 1];
@@ -197,7 +237,70 @@ void mag_spoof_two_track_rfid(FuriString* track1, FuriString* track2) {
197
237
for(uint8_t i = 0; i < ZERO_SUFFIX; i++) play_bit_rfid(0);
198
238
FURI_CRITICAL_EXIT();
199
239
200
- rfid_tx_reset ();
240
+ tx_reset_rfid();
241
+ }*/
242
+
243
+ void mag_spoof (Mag * mag ) {
244
+ MagSetting * setting = mag -> setting ;
245
+
246
+ // precompute tracks (WIP; ignores reverse and 3rd track)
247
+ // likely will be reworked to Samy's bitmap method anyway...
248
+ const char * data1 = furi_string_get_cstr (mag -> mag_dev -> dev_data .track [0 ].str );
249
+ const char * data2 = furi_string_get_cstr (mag -> mag_dev -> dev_data .track [0 ].str );
250
+ uint8_t bit_array1 [(strlen (data1 ) * bitlen [0 ]) + 1 ];
251
+ uint8_t bit_array2 [(strlen (data2 ) * bitlen [1 ]) + 1 ];
252
+ track_to_bits (bit_array1 , data1 , 0 );
253
+ track_to_bits (bit_array2 , data2 , 1 );
254
+
255
+ bool spoofed = false;
256
+ do {
257
+ // Initialize configured TX method
258
+ if (!tx_init (setting )) break ;
259
+
260
+ // Critical timing section (need to eliminate ifs? does this impact timing?)
261
+ FURI_CRITICAL_ENTER ();
262
+ // Prefix of zeros
263
+ for (uint8_t i = 0 ; i < ZERO_PREFIX ; i ++ ) {
264
+ if (!play_bit (0 , setting )) break ;
265
+ }
266
+
267
+ // Track 1
268
+ if ((setting -> track == MagTrackStateAll ) || (setting -> track == MagTrackStateOne )) {
269
+ for (uint8_t i = 0 ; bit_array1 [i ] != 2 ; i ++ ) {
270
+ if (!play_bit ((bit_array1 [i ] & 1 ), setting )) break ;
271
+ }
272
+ }
273
+
274
+ // Zeros between tracks
275
+ if (setting -> track == MagTrackStateAll ) {
276
+ for (uint8_t i = 0 ; i < ZERO_BETWEEN ; i ++ ) {
277
+ if (!play_bit (0 , setting )) break ;
278
+ }
279
+ }
280
+
281
+ // Track 2 (TODO: Reverse track)
282
+ if ((setting -> track == MagTrackStateAll ) || (setting -> track == MagTrackStateTwo )) {
283
+ for (uint8_t i = 0 ; bit_array2 [i ] != 2 ; i ++ ) {
284
+ if (!play_bit ((bit_array2 [i ] & 1 ), setting )) break ;
285
+ }
286
+ }
287
+
288
+ // Suffix of zeros
289
+ for (uint8_t i = 0 ; i < ZERO_SUFFIX ; i ++ ) {
290
+ if (!play_bit (0 , setting )) break ;
291
+ }
292
+ FURI_CRITICAL_EXIT ();
293
+
294
+ // Reset configured TX method
295
+ if (!tx_reset (setting )) break ;
296
+ spoofed = true;
297
+ } while (0 );
298
+
299
+ UNUSED (spoofed );
300
+ /*if(!spoofed) {
301
+ // error handling?
302
+ // cleanup?
303
+ }*/
201
304
}
202
305
203
306
//// @antirez's code from protoview for bitmapping. May want to refactor to use this...
0 commit comments