v1.1 - Add scan code (needs refactor)

This commit is contained in:
Derek Jamison 2023-09-13 21:56:30 -05:00
parent 384d618485
commit 7e8bdc0559
7 changed files with 166 additions and 2 deletions

View File

@ -5,6 +5,7 @@ App(
entry_point="wiegand_app",
requires=["gui"],
stack_size=2 * 1024,
fap_version=(1, 1),
fap_icon="wiegand.png",
fap_category="GPIO",
)

View File

@ -0,0 +1,5 @@
Filetype: Flipper Wiegand Key File
Version: 1
Protocol: RAW
Bits: 48
RAW_Data: D0 0 2243 D0 124823 127090 D0 249670 251937 D0 374517 376784 D0 499364 501631 D0 627194 629461 D0 752041 754307 D0 876888 879155 D0 1001753 1004020 D0 1126600 1128867 D0 1251447 1253714 D1 1376330 1378618 D0 1501154 1503415 D0 1626022 1628264 D0 1750845 1753111 D0 1875691 1877958 D0 2000557 2002824 D1 2125440 2127739 D1 2253284 2255577 D0 2378103 2380366 D1 2502981 2505267 D0 2627806 2630070 D0 2752650 2754917 D0 2877497 2879764 D0 3002363 3004629 D0 3127210 3129477 D0 3252057 3254324 D0 3376904 3379171 D0 3501751 3504017 D0 3626598 3628865 D1 3751479 3753765 D1 3879324 3881604 D1 4004200 4006479 D0 4129018 4131282 D1 4253897 4256182 D0 4378722 4380985 D1 4503600 4505886 D1 4628463 4630742 D1 4753319 4755599 D0 4878178 4880402 D1 5003035 5005321 D0 5127860 5130124 D0 5252704 5254971 D0 5380534 5382800 D1 5505415 5507694 D1 5630267 5632550 D0 5755117 5757360 D1 5879976 5882257

View File

@ -10,6 +10,7 @@ void wiegand_instructions_scene_on_enter(void* context) {
15,
128,
40,
"Version 1.1\n"
"Only use on devices you own!\n"
"Connect D0 (Green) to pin A4\n"
"Connect D1 (White) to pin A7\n"
@ -37,7 +38,6 @@ void wiegand_instructions_scene_on_enter(void* context) {
"Connect pin A4 to drain of\n"
"mosfet for D0. Connect\n"
"source of mosfet for D0 to\n"
"GND.\n"
);
"GND.\n");
view_dispatcher_switch_to_view(app->view_dispatcher, WiegandWidgetView);
}

View File

@ -15,6 +15,9 @@ void wiegand_menu_callback(void* context, uint32_t index) {
case WiegandMainMenuRead:
event = WiegandMainMenuReadEvent;
break;
case WiegandMainMenuScan:
event = WiegandMainMenuScanEvent;
break;
case WiegandMainMenuLoad:
event = WiegandMainMenuLoadEvent;
break;
@ -36,6 +39,8 @@ void wiegand_main_menu_scene_on_enter(void* context) {
submenu_add_item(
app->submenu, "Instructions", WiegandMainMenuInstructions, wiegand_menu_callback, app);
submenu_add_item(app->submenu, "Read", WiegandMainMenuRead, wiegand_menu_callback, app);
submenu_add_item(
app->submenu, "Scan w/AutoSave", WiegandMainMenuScan, wiegand_menu_callback, app);
submenu_add_item(app->submenu, "Load", WiegandMainMenuLoad, wiegand_menu_callback, app);
view_dispatcher_switch_to_view(app->view_dispatcher, WiegandSubmenuView);
}
@ -53,6 +58,10 @@ bool wiegand_main_menu_scene_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(app->scene_manager, WiegandReadScene);
consumed = true;
break;
case WiegandMainMenuScanEvent:
scene_manager_next_scene(app->scene_manager, WiegandScanScene);
consumed = true;
break;
case WiegandMainMenuLoadEvent:
scene_manager_next_scene(app->scene_manager, WiegandLoadScene);
consumed = true;

View File

@ -0,0 +1,139 @@
#include "../wiegand.h"
#include <furi_hal.h>
FuriTimer* timer = NULL;
static void wiegand_scan_isr_d0(void* context) {
UNUSED(context);
uint32_t time = DWT->CYCCNT;
bool rise = furi_hal_gpio_read(pinD0);
data[bit_count] = 0;
if(rise) {
data_rise[bit_count] = time;
if(bit_count < MAX_BITS) {
bit_count++;
}
} else {
data_fall[bit_count] = time;
}
}
static void wiegand_scan_isr_d1(void* context) {
UNUSED(context);
uint32_t time = DWT->CYCCNT;
bool rise = furi_hal_gpio_read(pinD1);
data[bit_count] = 1;
if(rise) {
data_rise[bit_count] = time;
if(bit_count < MAX_BITS) {
bit_count++;
}
} else {
data_fall[bit_count] = time;
}
}
static void wiegand_start_scan(void* context) {
UNUSED(context);
data_saved = false;
bit_count = 0;
furi_hal_gpio_init_simple(pinD0, GpioModeInterruptRiseFall);
furi_hal_gpio_init_simple(pinD1, GpioModeInterruptRiseFall);
furi_hal_gpio_add_int_callback(pinD0, wiegand_scan_isr_d0, NULL);
furi_hal_gpio_add_int_callback(pinD1, wiegand_scan_isr_d1, NULL);
furi_timer_start(timer, 100);
}
static void wiegand_stop_scan(void* context) {
UNUSED(context);
furi_hal_gpio_remove_int_callback(pinD0);
furi_hal_gpio_remove_int_callback(pinD1);
furi_hal_gpio_init_simple(pinD0, GpioModeAnalog);
furi_hal_gpio_init_simple(pinD1, GpioModeAnalog);
furi_timer_stop(timer);
}
static void wiegand_scan_found(void* context) {
App* app = context;
FuriHalRtcDateTime datetime;
furi_hal_rtc_get_datetime(&datetime);
snprintf(
app->file_name,
25,
"%02d%02d%02d_%02d%02d%02d",
datetime.year,
datetime.month,
datetime.day,
datetime.hour,
datetime.minute,
datetime.second);
furi_hal_vibro_on(true);
furi_delay_ms(50);
furi_hal_vibro_on(false);
furi_delay_ms(50);
wiegand_save(app);
furi_hal_vibro_on(true);
furi_delay_ms(50);
furi_hal_vibro_on(false);
furi_delay_ms(1000);
wiegand_start_scan(app);
}
static void wiegand_scan_timer_callback(void* context) {
App* app = context;
uint32_t duration = DWT->CYCCNT;
const uint32_t one_millisecond = 64000;
if(bit_count == 0) {
return;
}
duration -= data_fall[bit_count - 1];
bool found = false;
FURI_CRITICAL_ENTER();
if(duration > 25 * one_millisecond) {
if(bit_count == 4 || bit_count == 8 || bit_count == 24 || bit_count == 26 ||
bit_count == 32 || bit_count == 34 || bit_count == 37 || bit_count == 40 ||
bit_count == 48) {
wiegand_stop_scan(app);
found = true;
} else {
// No data, clear
bit_count = 0;
}
}
FURI_CRITICAL_EXIT();
if(found) {
wiegand_scan_found(app);
}
}
void wiegand_scan_scene_on_enter(void* context) {
App* app = context;
timer = furi_timer_alloc(wiegand_scan_timer_callback, FuriTimerTypePeriodic, app);
widget_reset(app->widget);
widget_add_string_element(app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Scan Wiegand");
widget_add_string_element(
app->widget, 0, 20, AlignLeft, AlignTop, FontSecondary, "Files saved automatically.");
widget_add_string_element(
app->widget, 0, 30, AlignLeft, AlignTop, FontSecondary, "Vibrates on detection.");
widget_add_string_element(
app->widget, 0, 45, AlignLeft, AlignTop, FontSecondary, "D0/Green/A4");
widget_add_string_element(
app->widget, 0, 53, AlignLeft, AlignTop, FontSecondary, "D1/White/A7");
wiegand_start_scan(app);
view_dispatcher_switch_to_view(app->view_dispatcher, WiegandWidgetView);
}
void wiegand_scan_scene_on_exit(void* context) {
App* app = context;
wiegand_stop_scan(app);
furi_timer_free(timer);
}

View File

@ -23,6 +23,7 @@ void (*const basic_scenes_scene_on_enter_handlers[])(void*) = {
wiegand_main_menu_scene_on_enter,
wiegand_instructions_scene_on_enter,
wiegand_read_scene_on_enter,
wiegand_scan_scene_on_enter,
wiegand_data_scene_on_enter,
wiegand_save_scene_on_enter,
wiegand_load_scene_on_enter,
@ -32,6 +33,7 @@ bool (*const basic_scenes_scene_on_event_handlers[])(void*, SceneManagerEvent) =
wiegand_main_menu_scene_on_event,
wiegand_empty_scene_on_event, // instructions
wiegand_empty_scene_on_event, // read
wiegand_empty_scene_on_event, // scan
wiegand_data_scene_on_event,
wiegand_save_scene_on_event,
wiegand_empty_scene_on_event, // load
@ -41,6 +43,7 @@ void (*const basic_scenes_scene_on_exit_handlers[])(void*) = {
wiegand_empty_scene_on_exit, // main_menu
wiegand_empty_scene_on_exit, // instructions
wiegand_read_scene_on_exit,
wiegand_scan_scene_on_exit,
wiegand_empty_scene_on_exit, // data
wiegand_empty_scene_on_exit, // save
wiegand_empty_scene_on_exit, // load

View File

@ -37,6 +37,7 @@ typedef enum {
WiegandMainMenuScene,
WiegandInstructionsScene,
WiegandReadScene,
WiegandScanScene,
WiegandDataScene,
WiegandSaveScene,
WiegandLoadScene,
@ -64,6 +65,7 @@ typedef struct App {
typedef enum {
WiegandMainMenuInstructions,
WiegandMainMenuRead,
WiegandMainMenuScan,
WiegandMainMenuLoad,
} WiegandMainMenuSceneIndex;
@ -71,6 +73,7 @@ typedef enum {
WiegandMainMenuUnknownEvent,
WiegandMainMenuInstructionsEvent,
WiegandMainMenuReadEvent,
WiegandMainMenuScanEvent,
WiegandMainMenuLoadEvent,
} WiegandMainMenuEvent;
@ -119,6 +122,10 @@ void wiegand_load_scene_on_enter(void* context);
bool wiegand_custom_callback(void* context, uint32_t custom_event);
bool wiegand_back_event_callback(void* context);
void wiegand_scan_scene_on_enter(void* context);
//bool wiegand_scan_scene_on_event(void* context, SceneManagerEvent event);
void wiegand_scan_scene_on_exit(void* context);
// Methods with no implementation.
bool wiegand_empty_scene_on_event(void* context, SceneManagerEvent event);
void wiegand_empty_scene_on_exit(void* _ctx);