forked from flipperdevices/flipperzero-firmware
-
-
Notifications
You must be signed in to change notification settings - Fork 547
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added historical spoofing implementation to the hardcoded emulation t…
…est ground
- Loading branch information
1 parent
f23ac31
commit ef1cb1b
Showing
1 changed file
with
167 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,183 @@ | ||
#include "../mag_i.h" | ||
|
||
#define PIN_A 0 | ||
#define PIN_B 1 // currently unused | ||
#define CLOCK_US 250 // typically set between 200-500us | ||
|
||
uint8_t magspoof_bit_dir = 0; | ||
|
||
void mag_scene_emulate_test_dialog_callback(DialogExResult result, void* context) { | ||
Mag* mag = context; | ||
|
||
view_dispatcher_send_custom_event(mag->view_dispatcher, result); | ||
} | ||
|
||
void gpio_item_set_rfid_pin(uint8_t index, bool level) { | ||
if(index == 0) { | ||
furi_hal_gpio_write(&gpio_rfid_carrier_out, level); | ||
// A7 GPIO pin for debugging purposes | ||
//furi_hal_gpio_write(&gpio_ext_pa7, level); | ||
} | ||
} | ||
|
||
static void play_bit(uint8_t send_bit) { | ||
magspoof_bit_dir ^= 1; | ||
gpio_item_set_rfid_pin(PIN_A, magspoof_bit_dir); | ||
// PIN_B goes unused in current LF modulation. | ||
// Leaving legacy here in event we attempt downstream modulation, | ||
// rather than just modulating RFID_OUT upstream for signal forming | ||
gpio_item_set_rfid_pin(PIN_B, !magspoof_bit_dir); | ||
furi_delay_us(CLOCK_US); | ||
|
||
if(send_bit) { | ||
magspoof_bit_dir ^= 1; | ||
gpio_item_set_rfid_pin(PIN_A, magspoof_bit_dir); | ||
gpio_item_set_rfid_pin(PIN_B, !magspoof_bit_dir); | ||
} | ||
furi_delay_us(CLOCK_US); | ||
} | ||
|
||
static void mag_spoof(FuriString* track_str, uint8_t track) { | ||
furi_hal_power_enable_otg(); | ||
|
||
size_t from; | ||
size_t to; | ||
|
||
// TODO ';' in first track case | ||
if(track == 0) { | ||
from = furi_string_search_char(track_str, '%'); | ||
to = furi_string_search_char(track_str, '?', from); | ||
} else if(track == 1) { | ||
from = furi_string_search_char(track_str, ';'); | ||
to = furi_string_search_char(track_str, '?', from); | ||
} else { | ||
from = 0; | ||
to = furi_string_size(track_str); | ||
} | ||
if(from >= to) { | ||
return; | ||
} | ||
furi_string_mid(track_str, from, to - from + 1); | ||
|
||
const char* data = furi_string_get_cstr(track_str); | ||
|
||
printf("%s", data); | ||
|
||
furi_hal_ibutton_start_drive(); | ||
furi_hal_ibutton_pin_low(); | ||
|
||
// this doesn't seem to make a difference, leaving it in | ||
furi_hal_gpio_init(&gpio_rfid_data_in, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); | ||
furi_hal_gpio_write(&gpio_rfid_data_in, false); | ||
|
||
// false->ground RFID antenna; true->don't ground | ||
// skotopes (RFID dev) say normally you'd want RFID_PULL in high for signal forming, while modulating RFID_OUT | ||
// dunaevai135 had it low in their old code. Leaving low, as it doesn't seem to make a difference on my janky antenna | ||
furi_hal_gpio_init(&gpio_nfc_irq_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); | ||
furi_hal_gpio_write(&gpio_nfc_irq_rfid_pull, false); | ||
|
||
furi_hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); | ||
|
||
// A7 GPIO pin for debugging purposes | ||
//furi_hal_gpio_init(&gpio_ext_pa7, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); | ||
|
||
furi_delay_ms(300); | ||
|
||
FURI_CRITICAL_ENTER(); | ||
|
||
const uint8_t bitlen[] = {7, 5, 5}; | ||
const int sublen[] = {32, 48, 48}; | ||
int tmp, crc, lrc = 0; | ||
magspoof_bit_dir = 0; | ||
|
||
// First put out a bunch of leading zeros. | ||
for(uint8_t i = 0; i < 25; i++) { | ||
play_bit(0); | ||
} | ||
|
||
for(uint8_t i = 0; data[i] != '\0'; i++) { | ||
crc = 1; | ||
tmp = data[i] - sublen[track]; | ||
|
||
for(uint8_t j = 0; j < bitlen[track] - 1; j++) { | ||
crc ^= tmp & 1; | ||
lrc ^= (tmp & 1) << j; | ||
play_bit(tmp & 1); | ||
tmp >>= 1; | ||
} | ||
play_bit(crc); | ||
} | ||
|
||
// finish calculating and send last "byte" (LRC) | ||
tmp = lrc; | ||
crc = 1; | ||
for(uint8_t j = 0; j < bitlen[track] - 1; j++) { | ||
crc ^= tmp & 1; | ||
play_bit(tmp & 1); | ||
tmp >>= 1; | ||
} | ||
play_bit(crc); | ||
|
||
// finish with 0's | ||
for(uint8_t i = 0; i < 5 * 5; i++) { | ||
play_bit(0); | ||
} | ||
|
||
gpio_item_set_rfid_pin(PIN_A, 0); | ||
gpio_item_set_rfid_pin(PIN_B, 0); | ||
|
||
FURI_CRITICAL_EXIT(); | ||
|
||
furi_hal_rfid_pins_reset(); | ||
furi_hal_power_disable_otg(); | ||
} | ||
|
||
void mag_scene_emulate_test_on_enter(void* context) { | ||
Mag* mag = context; | ||
UNUSED(mag); | ||
Widget* widget = mag->widget; | ||
|
||
FuriString* tmp_string; | ||
tmp_string = furi_string_alloc(); | ||
|
||
widget_add_button_element(widget, GuiButtonTypeLeft, "Back", mag_widget_callback, mag); | ||
widget_add_button_element(widget, GuiButtonTypeCenter, "Emulate", mag_widget_callback, mag); | ||
|
||
furi_string_printf(tmp_string, "Emulate?"); | ||
widget_add_string_element( | ||
widget, 64, 0, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); | ||
furi_string_reset(tmp_string); | ||
|
||
view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewWidget); | ||
furi_string_free(tmp_string); | ||
} | ||
|
||
bool mag_scene_emulate_test_on_event(void* context, SceneManagerEvent event) { | ||
Mag* mag = context; | ||
UNUSED(mag); | ||
UNUSED(event); | ||
SceneManager* scene_manager = mag->scene_manager; | ||
bool consumed = false; | ||
|
||
if(event.type == SceneManagerEventTypeCustom) { | ||
if(event.event == DialogExResultCenter) { | ||
consumed = true; | ||
|
||
// Hardcoding a test string for the time being, while we debug/improve LF RFID TX | ||
FuriString* v = furi_string_alloc(); | ||
furi_string_set_str( | ||
v, | ||
"%B123456781234567^LASTNAME/FIRST^YYMMSSSDDDDDDDDDDDDDDDDDDDDDDDDD?;1234567812?"); | ||
mag_spoof(v, 0); | ||
furi_string_free(v); | ||
} else if(event.event == GuiButtonTypeLeft) { | ||
consumed = true; | ||
|
||
scene_manager_previous_scene(scene_manager); | ||
} | ||
} | ||
|
||
return consumed; | ||
} | ||
|
||
void mag_scene_emulate_test_on_exit(void* context) { | ||
Mag* mag = context; | ||
UNUSED(mag); | ||
widget_reset(mag->widget); | ||
} |