mirror of
https://github.com/D4C1-Labs/Flipper-ARF.git
synced 2026-03-30 05:09:53 +00:00
Compare commits
4 Commits
dev-4e05a0
...
dev-a5cf67
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5cf675561 | ||
|
|
c6bec5ef4f | ||
|
|
883d387246 | ||
|
|
951f35c356 |
@@ -282,6 +282,7 @@ static Desktop* desktop_alloc(void) {
|
||||
desktop->pin_input_view = desktop_view_pin_input_alloc();
|
||||
desktop->pin_timeout_view = desktop_view_pin_timeout_alloc();
|
||||
desktop->slideshow_view = desktop_view_slideshow_alloc();
|
||||
desktop->tos_view = desktop_view_tos_alloc();
|
||||
|
||||
desktop->main_view_stack = view_stack_alloc();
|
||||
desktop->main_view = desktop_main_alloc();
|
||||
@@ -326,6 +327,10 @@ static Desktop* desktop_alloc(void) {
|
||||
desktop->view_dispatcher,
|
||||
DesktopViewIdSlideshow,
|
||||
desktop_view_slideshow_get_view(desktop->slideshow_view));
|
||||
view_dispatcher_add_view(
|
||||
desktop->view_dispatcher,
|
||||
DesktopViewIdTos,
|
||||
desktop_view_tos_get_view(desktop->tos_view));
|
||||
|
||||
// Lock icon
|
||||
desktop->lock_icon_viewport = view_port_alloc();
|
||||
@@ -513,6 +518,8 @@ int32_t desktop_srv(void* p) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow);
|
||||
}
|
||||
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneTos);
|
||||
|
||||
if(!furi_hal_version_do_i_belong_here()) {
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneHwMismatch);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "views/desktop_view_lock_menu.h"
|
||||
#include "views/desktop_view_debug.h"
|
||||
#include "views/desktop_view_slideshow.h"
|
||||
#include "views/desktop_view_tos.h"
|
||||
#include "helpers/arf_boot_jingle.h"
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view_stack.h>
|
||||
@@ -32,6 +34,7 @@ typedef enum {
|
||||
DesktopViewIdPinInput,
|
||||
DesktopViewIdPinTimeout,
|
||||
DesktopViewIdSlideshow,
|
||||
DesktopViewIdTos,
|
||||
DesktopViewIdTotal,
|
||||
} DesktopViewId;
|
||||
|
||||
@@ -55,6 +58,7 @@ struct Desktop {
|
||||
DesktopMainView* main_view;
|
||||
DesktopViewPinTimeout* pin_timeout_view;
|
||||
DesktopSlideshowView* slideshow_view;
|
||||
DesktopViewTos* tos_view;
|
||||
DesktopViewPinInput* pin_input_view;
|
||||
|
||||
ViewStack* main_view_stack;
|
||||
|
||||
98
applications/services/desktop/helpers/arf_boot_jingle.c
Normal file
98
applications/services/desktop/helpers/arf_boot_jingle.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "arf_boot_jingle.h"
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal_speaker.h>
|
||||
|
||||
typedef struct {
|
||||
float frequency;
|
||||
uint32_t duration_ms;
|
||||
} ArfBootNote;
|
||||
|
||||
static const ArfBootNote arf_boot_jingle[] = {
|
||||
{1046.50f, 50},
|
||||
{1046.50f, 200},
|
||||
{0.0f, 100},
|
||||
{783.99f, 300},
|
||||
{0.0f, 50},
|
||||
{659.26f, 300},
|
||||
{0.0f, 50},
|
||||
{783.99f, 250},
|
||||
{880.00f, 100},
|
||||
{880.00f, 100},
|
||||
{783.99f, 300},
|
||||
{1046.50f, 150},
|
||||
{1318.51f, 150},
|
||||
{1760.00f, 250},
|
||||
{1396.91f, 150},
|
||||
{1567.98f, 100},
|
||||
{1318.51f, 250},
|
||||
{1174.66f, 150},
|
||||
{1396.91f, 150},
|
||||
{1318.51f, 400},
|
||||
{392.00f, 100},
|
||||
{523.25f, 300},
|
||||
{0.0f, 50},
|
||||
{1567.98f, 150},
|
||||
{1479.98f, 150},
|
||||
{1396.91f, 150},
|
||||
{1174.66f, 250},
|
||||
{1318.51f, 300},
|
||||
{783.99f, 150},
|
||||
{1046.50f, 100},
|
||||
{1318.51f, 100},
|
||||
{783.99f, 100},
|
||||
{1046.50f, 100},
|
||||
{1318.51f, 150},
|
||||
{0.0f, 50},
|
||||
{1567.98f, 150},
|
||||
{1479.98f, 100},
|
||||
{1396.91f, 150},
|
||||
{1174.66f, 250},
|
||||
{1318.51f, 300},
|
||||
{0.0f, 50},
|
||||
{2093.00f, 700},
|
||||
};
|
||||
|
||||
static const uint32_t arf_boot_jingle_len =
|
||||
sizeof(arf_boot_jingle) / sizeof(arf_boot_jingle[0]);
|
||||
|
||||
static FuriThread* jingle_thread = NULL;
|
||||
|
||||
static int32_t arf_jingle_thread_cb(void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
if(!furi_hal_speaker_acquire(1000)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < arf_boot_jingle_len; i++) {
|
||||
const ArfBootNote* note = &arf_boot_jingle[i];
|
||||
if(note->frequency == 0.0f) {
|
||||
furi_hal_speaker_stop();
|
||||
} else {
|
||||
furi_hal_speaker_start(note->frequency, 0.8f);
|
||||
}
|
||||
furi_delay_ms(note->duration_ms);
|
||||
}
|
||||
|
||||
furi_hal_speaker_stop();
|
||||
furi_hal_speaker_release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arf_boot_jingle_play(void) {
|
||||
if(jingle_thread != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
jingle_thread = furi_thread_alloc_ex("ArfJingle", 512, arf_jingle_thread_cb, NULL);
|
||||
furi_thread_start(jingle_thread);
|
||||
}
|
||||
|
||||
void arf_boot_jingle_stop(void) {
|
||||
if(jingle_thread != NULL) {
|
||||
furi_thread_join(jingle_thread);
|
||||
furi_thread_free(jingle_thread);
|
||||
jingle_thread = NULL;
|
||||
}
|
||||
}
|
||||
4
applications/services/desktop/helpers/arf_boot_jingle.h
Normal file
4
applications/services/desktop/helpers/arf_boot_jingle.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void arf_boot_jingle_play(void);
|
||||
void arf_boot_jingle_stop(void);
|
||||
@@ -8,3 +8,4 @@ ADD_SCENE(desktop, pin_input, PinInput)
|
||||
ADD_SCENE(desktop, pin_timeout, PinTimeout)
|
||||
ADD_SCENE(desktop, slideshow, Slideshow)
|
||||
ADD_SCENE(desktop, secure_enclave, SecureEnclave)
|
||||
ADD_SCENE(desktop, tos, Tos)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../desktop_i.h"
|
||||
#include "../views/desktop_view_slideshow.h"
|
||||
#include "../views/desktop_events.h"
|
||||
#include "desktop_scene.h"
|
||||
#include <power/power_service/power.h>
|
||||
|
||||
void desktop_scene_slideshow_callback(DesktopEvent event, void* context) {
|
||||
|
||||
52
applications/services/desktop/scenes/desktop_scene_tos.c
Normal file
52
applications/services/desktop/scenes/desktop_scene_tos.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <power/power_service/power.h>
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
#include "desktop_scene.h"
|
||||
#include "../desktop_i.h"
|
||||
#include "../views/desktop_events.h"
|
||||
#include "../views/desktop_view_tos.h"
|
||||
|
||||
static void desktop_scene_tos_callback(DesktopEvent event, void* context) {
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void desktop_scene_tos_on_enter(void* context) {
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
|
||||
arf_boot_jingle_play();
|
||||
|
||||
gui_set_hide_status_bar(desktop->gui, true);
|
||||
desktop_view_tos_set_callback(desktop->tos_view, desktop_scene_tos_callback, desktop);
|
||||
view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdTos);
|
||||
}
|
||||
|
||||
bool desktop_scene_tos_on_event(void* context, SceneManagerEvent event) {
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case DesktopTosAccepted:
|
||||
scene_manager_previous_scene(desktop->scene_manager);
|
||||
consumed = true;
|
||||
break;
|
||||
case DesktopTosDeclined: {
|
||||
Power* power = furi_record_open(RECORD_POWER);
|
||||
power_off(power);
|
||||
furi_record_close(RECORD_POWER);
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void desktop_scene_tos_on_exit(void* context) {
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
arf_boot_jingle_stop();
|
||||
gui_set_hide_status_bar(desktop->gui, false);
|
||||
}
|
||||
@@ -39,6 +39,8 @@ typedef enum {
|
||||
|
||||
DesktopSlideshowCompleted,
|
||||
DesktopSlideshowPoweroff,
|
||||
DesktopTosAccepted,
|
||||
DesktopTosDeclined,
|
||||
|
||||
DesktopHwMismatchExit,
|
||||
|
||||
|
||||
79
applications/services/desktop/views/desktop_view_tos.c
Normal file
79
applications/services/desktop/views/desktop_view_tos.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <furi.h>
|
||||
#include "desktop_view_tos.h"
|
||||
|
||||
struct DesktopViewTos {
|
||||
View* view;
|
||||
DesktopViewTosCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
static void desktop_view_tos_draw(Canvas* canvas, void* model) {
|
||||
UNUSED(model);
|
||||
canvas_clear(canvas);
|
||||
|
||||
static const uint8_t mario_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcc,0x00,0x00,0x82,0x01,0x00,
|
||||
0xc1,0x00,0x00,0xe1,0x07,0x80,0x09,0x08,0x40,0x46,0x07,0x40,0x42,0x03,0x40,0x08,
|
||||
0x04,0x80,0x30,0x04,0x00,0xf1,0x04,0x80,0x82,0x07,0x20,0xfc,0x00,0x30,0x7e,0x00,
|
||||
0x10,0x91,0x00,0x10,0xa0,0x02,0xe0,0x20,0x05,0x60,0x31,0x07,0xf0,0xfb,0x03,0xf0,
|
||||
0xe3,0x00,0xe8,0xe9,0x00,0x08,0xfe,0x00,0x1c,0x7c,0x01,0xf4,0x1f,0x06,0xe4,0x13,
|
||||
0x0e,0x84,0x90,0x09,0x84,0x40,0x08,0x88,0x20,0x06,0x70,0xe0,0x03,0x00,0x00,0x00};
|
||||
|
||||
canvas_draw_xbm(canvas, 105, 0, 22, 32, mario_bits);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 2, 11, "Term of use:");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 3, 22, "Authorize RF research");
|
||||
canvas_draw_str(canvas, 3, 30, "use ONLY. Unauthorized");
|
||||
canvas_draw_str(canvas, 3, 39, "use is prohibited.");
|
||||
canvas_draw_str(canvas, 2, 61, "Back=Shutdown");
|
||||
canvas_draw_str(canvas, 80, 62, "Ok=Accept");
|
||||
}
|
||||
|
||||
static bool desktop_view_tos_input(InputEvent* event, void* context) {
|
||||
furi_assert(event);
|
||||
DesktopViewTos* instance = context;
|
||||
|
||||
if(event->type == InputTypeShort) {
|
||||
if(event->key == InputKeyOk) {
|
||||
instance->callback(DesktopTosAccepted, instance->context);
|
||||
return true;
|
||||
} else if(event->key == InputKeyBack) {
|
||||
instance->callback(DesktopTosDeclined, instance->context);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DesktopViewTos* desktop_view_tos_alloc(void) {
|
||||
DesktopViewTos* instance = malloc(sizeof(DesktopViewTos));
|
||||
instance->view = view_alloc();
|
||||
view_set_context(instance->view, instance);
|
||||
view_set_draw_callback(instance->view, desktop_view_tos_draw);
|
||||
view_set_input_callback(instance->view, desktop_view_tos_input);
|
||||
return instance;
|
||||
}
|
||||
|
||||
void desktop_view_tos_free(DesktopViewTos* instance) {
|
||||
furi_assert(instance);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* desktop_view_tos_get_view(DesktopViewTos* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
||||
|
||||
void desktop_view_tos_set_callback(
|
||||
DesktopViewTos* instance,
|
||||
DesktopViewTosCallback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
instance->callback = callback;
|
||||
instance->context = context;
|
||||
}
|
||||
14
applications/services/desktop/views/desktop_view_tos.h
Normal file
14
applications/services/desktop/views/desktop_view_tos.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <gui/view.h>
|
||||
#include "desktop_events.h"
|
||||
|
||||
typedef struct DesktopViewTos DesktopViewTos;
|
||||
typedef void (*DesktopViewTosCallback)(DesktopEvent event, void* context);
|
||||
|
||||
DesktopViewTos* desktop_view_tos_alloc(void);
|
||||
void desktop_view_tos_free(DesktopViewTos* instance);
|
||||
View* desktop_view_tos_get_view(DesktopViewTos* instance);
|
||||
void desktop_view_tos_set_callback(
|
||||
DesktopViewTos* instance,
|
||||
DesktopViewTosCallback callback,
|
||||
void* context);
|
||||
@@ -55,7 +55,6 @@ typedef struct SubGhzProtocolDecoderFordV0 {
|
||||
uint32_t serial;
|
||||
uint8_t button;
|
||||
uint32_t count;
|
||||
uint8_t bs_magic;
|
||||
} SubGhzProtocolDecoderFordV0;
|
||||
typedef struct SubGhzProtocolEncoderFordV0 {
|
||||
SubGhzProtocolEncoderBase base;
|
||||
@@ -67,8 +66,7 @@ typedef struct SubGhzProtocolEncoderFordV0 {
|
||||
uint32_t serial;
|
||||
uint8_t button;
|
||||
uint32_t count;
|
||||
uint8_t bs;
|
||||
uint8_t bs_magic;
|
||||
uint8_t checksum;
|
||||
} SubGhzProtocolEncoderFordV0;
|
||||
typedef enum {
|
||||
FordV0DecoderStepReset = 0,
|
||||
@@ -88,14 +86,13 @@ static void decode_ford_v0(
|
||||
uint16_t key2,
|
||||
uint32_t* serial,
|
||||
uint8_t* button,
|
||||
uint32_t* count,
|
||||
uint8_t* bs_magic);
|
||||
uint32_t* count);
|
||||
static void encode_ford_v0(
|
||||
uint8_t header_byte,
|
||||
uint32_t serial,
|
||||
uint8_t button,
|
||||
uint32_t count,
|
||||
uint8_t bs,
|
||||
uint8_t checksum,
|
||||
uint64_t* key1);
|
||||
static bool ford_v0_process_data(SubGhzProtocolDecoderFordV0* instance);
|
||||
|
||||
@@ -122,7 +119,6 @@ const SubGhzProtocolEncoder subghz_protocol_ford_v0_encoder = {
|
||||
.yield = subghz_protocol_encoder_ford_v0_yield,
|
||||
};
|
||||
|
||||
|
||||
const SubGhzProtocol subghz_protocol_ford_v0 = {
|
||||
.name = FORD_PROTOCOL_V0_NAME,
|
||||
.type = SubGhzProtocolTypeDynamic,
|
||||
@@ -133,19 +129,19 @@ const SubGhzProtocol subghz_protocol_ford_v0 = {
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
// BS CALCULATION
|
||||
// BS = (counter_low_byte + 0x6F + (button << 4)) & 0xFF
|
||||
// Checksum CALCULATION
|
||||
// checksum = sum of bytes 1-7
|
||||
// =============================================================================
|
||||
static uint8_t ford_v0_calculate_bs_from_buf(uint8_t* buf) {
|
||||
// BS = sum of bytes 1..7 of the pre-XOR buffer
|
||||
static uint8_t ford_v0_calculate_checksum_from_buf(uint8_t* buf) {
|
||||
// Checksum = sum of bytes 1..7 of the pre-XOR buffer
|
||||
uint8_t checksum = 0;
|
||||
for(int i = 1; i <= 7; i++) checksum += buf[i];
|
||||
for(int i = 1; i <= 7; i++)
|
||||
checksum += buf[i];
|
||||
return checksum;
|
||||
}
|
||||
// =============================================================================
|
||||
// CRC FUNCTIONS
|
||||
// =============================================================================
|
||||
|
||||
static uint8_t ford_v0_popcount8(uint8_t x) {
|
||||
uint8_t count = 0;
|
||||
while(x) {
|
||||
@@ -171,14 +167,14 @@ static uint8_t ford_v0_calculate_crc(uint8_t* buf) {
|
||||
|
||||
return crc;
|
||||
}
|
||||
static uint8_t ford_v0_calculate_crc_for_tx(uint64_t key1, uint8_t bs) {
|
||||
static uint8_t ford_v0_calculate_crc_for_tx(uint64_t key1, uint8_t checksum) {
|
||||
uint8_t buf[16] = {0};
|
||||
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
buf[i] = (uint8_t)(key1 >> (56 - i * 8));
|
||||
}
|
||||
|
||||
buf[8] = bs;
|
||||
buf[8] = checksum;
|
||||
|
||||
uint8_t crc = ford_v0_calculate_crc(buf);
|
||||
return crc ^ 0x80;
|
||||
@@ -207,8 +203,7 @@ static void decode_ford_v0(
|
||||
uint16_t key2,
|
||||
uint32_t* serial,
|
||||
uint8_t* button,
|
||||
uint32_t* count,
|
||||
uint8_t* bs_magic) {
|
||||
uint32_t* count) {
|
||||
uint8_t buf[13] = {0};
|
||||
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
@@ -219,7 +214,7 @@ static void decode_ford_v0(
|
||||
buf[9] = (uint8_t)(key2 & 0xFF);
|
||||
|
||||
uint8_t tmp = buf[8];
|
||||
uint8_t bs = tmp;
|
||||
//uint8_t checksum = tmp; //KEPT FOR CLARITY
|
||||
uint8_t parity = 0;
|
||||
uint8_t parity_any = (tmp != 0);
|
||||
while(tmp) {
|
||||
@@ -261,9 +256,6 @@ static void decode_ford_v0(
|
||||
*button = (buf[5] >> 4) & 0x0F;
|
||||
|
||||
*count = ((buf[5] & 0x0F) << 16) | (buf[6] << 8) | buf[7];
|
||||
|
||||
// BS is checksum of bytes 1..7 (pre-XOR), stored for verification only
|
||||
*bs_magic = bs; // kept for compatibility, not used in encode
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -274,7 +266,7 @@ static void encode_ford_v0(
|
||||
uint32_t serial,
|
||||
uint8_t button,
|
||||
uint32_t count,
|
||||
uint8_t bs,
|
||||
uint8_t checksum,
|
||||
uint64_t* key1) {
|
||||
if(!key1) {
|
||||
FURI_LOG_E(TAG, "encode_ford_v0: NULL key1 pointer");
|
||||
@@ -301,19 +293,19 @@ static void encode_ford_v0(
|
||||
buf[6] = pre_xor_6;
|
||||
buf[7] = pre_xor_7;
|
||||
|
||||
// BS = checksum of bytes 1..7 before XOR
|
||||
bs = ford_v0_calculate_bs_from_buf(buf);
|
||||
//checksum = checksum of bytes 1..7 before XOR
|
||||
checksum = ford_v0_calculate_checksum_from_buf(buf);
|
||||
|
||||
uint8_t post_xor_6 = (count_mid & 0xAA) | (count_low & 0x55);
|
||||
uint8_t post_xor_7 = (count_low & 0xAA) | (count_mid & 0x55);
|
||||
|
||||
uint8_t parity = 0;
|
||||
uint8_t tmp = bs;
|
||||
uint8_t tmp = checksum;
|
||||
while(tmp) {
|
||||
parity ^= (tmp & 1);
|
||||
tmp >>= 1;
|
||||
}
|
||||
bool parity_bit = (bs != 0) ? (parity != 0) : false;
|
||||
bool parity_bit = (checksum != 0) ? (parity != 0) : false;
|
||||
|
||||
if(parity_bit) {
|
||||
uint8_t xor_byte = post_xor_7;
|
||||
@@ -342,11 +334,11 @@ static void encode_ford_v0(
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Encode: Sn=%08lX Btn=%d Cnt=%05lX BS=%02X",
|
||||
"Encode: Sn=%08lX Btn=%d Cnt=%05lX Checksum=%02X",
|
||||
(unsigned long)serial,
|
||||
button,
|
||||
(unsigned long)count,
|
||||
bs);
|
||||
checksum);
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Encode key1: %08lX%08lX",
|
||||
@@ -361,10 +353,10 @@ static void encode_ford_v0(
|
||||
static uint8_t subghz_protocol_ford_v0_get_btn_code(void) {
|
||||
uint8_t custom_btn = subghz_custom_btn_get();
|
||||
uint8_t original_btn = subghz_custom_btn_get_original();
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_OK) return original_btn;
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_UP) return 0x01; // Lock
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_DOWN) return 0x02; // Unlock
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_LEFT) return 0x04; // Boot/Trunk
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_OK) return original_btn;
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_UP) return 0x01; // Lock
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_DOWN) return 0x02; // Unlock
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_LEFT) return 0x04; // Boot/Trunk
|
||||
if(custom_btn == SUBGHZ_CUSTOM_BTN_RIGHT) return 0x04; // Boot/Trunk
|
||||
return original_btn;
|
||||
}
|
||||
@@ -387,8 +379,7 @@ void* subghz_protocol_encoder_ford_v0_alloc(SubGhzEnvironment* environment) {
|
||||
instance->serial = 0;
|
||||
instance->button = 0;
|
||||
instance->count = 0;
|
||||
instance->bs = 0;
|
||||
instance->bs_magic = 0;
|
||||
instance->checksum = 0;
|
||||
|
||||
FURI_LOG_I(TAG, "Encoder allocated");
|
||||
return instance;
|
||||
@@ -586,14 +577,6 @@ SubGhzProtocolStatus
|
||||
break;
|
||||
}
|
||||
instance->generic.cnt = instance->count;
|
||||
|
||||
flipper_format_rewind(flipper_format);
|
||||
uint32_t bs_magic_temp = 0;
|
||||
if(!flipper_format_read_uint32(flipper_format, "BSMagic", &bs_magic_temp, 1))
|
||||
instance->bs_magic = 0x6F;
|
||||
else
|
||||
instance->bs_magic = (uint8_t)bs_magic_temp;
|
||||
|
||||
instance->count = (instance->count + 1) & 0xFFFFF;
|
||||
instance->generic.cnt = instance->count;
|
||||
|
||||
@@ -604,27 +587,33 @@ SubGhzProtocolStatus
|
||||
|
||||
instance->button = subghz_protocol_ford_v0_get_btn_code();
|
||||
|
||||
// BS is calculated inside encode_ford_v0 from buf[1..7]
|
||||
instance->bs = 0; // will be set by encode_ford_v0
|
||||
// Checksum is calculated inside encode_ford_v0 from buf[1..7]
|
||||
instance->checksum = 0; // will be set by encode_ford_v0
|
||||
|
||||
encode_ford_v0(
|
||||
header_byte,
|
||||
instance->serial,
|
||||
instance->button,
|
||||
instance->count,
|
||||
instance->bs,
|
||||
instance->checksum,
|
||||
&instance->key1);
|
||||
|
||||
instance->generic.data = instance->key1;
|
||||
instance->generic.data_count_bit = 64;
|
||||
|
||||
uint8_t calculated_crc = ford_v0_calculate_crc_for_tx(instance->key1, instance->bs);
|
||||
instance->key2 = ((uint16_t)instance->bs << 8) | calculated_crc;
|
||||
uint8_t calculated_crc = ford_v0_calculate_crc_for_tx(instance->key1, instance->checksum);
|
||||
instance->key2 = ((uint16_t)instance->checksum << 8) | calculated_crc;
|
||||
|
||||
FURI_LOG_I(TAG, "Encoded: Sn=%08lX Btn=%02X Cnt=%05lX BS=%02X CRC=%02X key1=%08lX%08lX",
|
||||
(unsigned long)instance->serial, instance->button,
|
||||
(unsigned long)instance->count, instance->bs, calculated_crc,
|
||||
(unsigned long)(instance->key1 >> 32), (unsigned long)(instance->key1 & 0xFFFFFFFF));
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Encoded: Sn=%08lX Btn=%02X Cnt=%05lX Checksum=%02X CRC=%02X key1=%08lX%08lX",
|
||||
(unsigned long)instance->serial,
|
||||
instance->button,
|
||||
(unsigned long)instance->count,
|
||||
instance->checksum,
|
||||
calculated_crc,
|
||||
(unsigned long)(instance->key1 >> 32),
|
||||
(unsigned long)(instance->key1 & 0xFFFFFFFF));
|
||||
|
||||
flipper_format_rewind(flipper_format);
|
||||
if(!flipper_format_read_uint32(
|
||||
@@ -649,8 +638,8 @@ SubGhzProtocolStatus
|
||||
bool cnt_wr = flipper_format_insert_or_update_uint32(flipper_format, "Cnt", &temp, 1);
|
||||
temp = calculated_crc;
|
||||
flipper_format_insert_or_update_uint32(flipper_format, "CRC", &temp, 1);
|
||||
temp = instance->bs;
|
||||
flipper_format_insert_or_update_uint32(flipper_format, "BS", &temp, 1);
|
||||
temp = instance->checksum;
|
||||
flipper_format_insert_or_update_uint32(flipper_format, "Checksum", &temp, 1);
|
||||
|
||||
FURI_LOG_I(TAG, "File updated: Key ok=%d Cnt ok=%d", key_wr, cnt_wr);
|
||||
|
||||
@@ -715,12 +704,7 @@ static bool ford_v0_process_data(SubGhzProtocolDecoderFordV0* instance) {
|
||||
uint16_t key2 = ~key2_raw;
|
||||
|
||||
decode_ford_v0(
|
||||
instance->key1,
|
||||
key2,
|
||||
&instance->serial,
|
||||
&instance->button,
|
||||
&instance->count,
|
||||
&instance->bs_magic);
|
||||
instance->key1, key2, &instance->serial, &instance->button, &instance->count);
|
||||
|
||||
instance->key2 = key2;
|
||||
return true;
|
||||
@@ -759,7 +743,6 @@ void subghz_protocol_decoder_ford_v0_reset(void* context) {
|
||||
instance->serial = 0;
|
||||
instance->button = 0;
|
||||
instance->count = 0;
|
||||
instance->bs_magic = 0;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_ford_v0_feed(void* context, bool level, uint32_t duration) {
|
||||
@@ -884,7 +867,7 @@ SubGhzProtocolStatus subghz_protocol_decoder_ford_v0_serialize(
|
||||
|
||||
if(ret == SubGhzProtocolStatusOk) {
|
||||
uint32_t temp = (instance->key2 >> 8) & 0xFF;
|
||||
flipper_format_write_uint32(flipper_format, "BS", &temp, 1);
|
||||
flipper_format_write_uint32(flipper_format, "Checksum", &temp, 1);
|
||||
|
||||
temp = instance->key2 & 0xFF;
|
||||
flipper_format_write_uint32(flipper_format, "CRC", &temp, 1);
|
||||
@@ -895,9 +878,6 @@ SubGhzProtocolStatus subghz_protocol_decoder_ford_v0_serialize(
|
||||
flipper_format_write_uint32(flipper_format, "Btn", &temp, 1);
|
||||
|
||||
flipper_format_write_uint32(flipper_format, "Cnt", &instance->count, 1);
|
||||
|
||||
temp = (uint32_t)instance->bs_magic;
|
||||
flipper_format_write_uint32(flipper_format, "BSMagic", &temp, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -911,7 +891,9 @@ SubGhzProtocolStatus
|
||||
SubGhzProtocolStatus ret = subghz_block_generic_deserialize_check_count_bit(
|
||||
&instance->generic, flipper_format, subghz_protocol_ford_v0_const.min_count_bit_for_found);
|
||||
|
||||
FURI_LOG_I(TAG, "Decoder deserialize: generic_ret=%d generic.data=%08lX%08lX",
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Decoder deserialize: generic_ret=%d generic.data=%08lX%08lX",
|
||||
ret,
|
||||
(unsigned long)(instance->generic.data >> 32),
|
||||
(unsigned long)(instance->generic.data & 0xFFFFFFFF));
|
||||
@@ -921,12 +903,17 @@ SubGhzProtocolStatus
|
||||
|
||||
flipper_format_rewind(flipper_format);
|
||||
|
||||
uint32_t bs_temp = 0;
|
||||
uint32_t checksum_temp = 0;
|
||||
uint32_t crc_temp = 0;
|
||||
flipper_format_read_uint32(flipper_format, "BS", &bs_temp, 1);
|
||||
flipper_format_read_uint32(flipper_format, "Checksum", &checksum_temp, 1);
|
||||
flipper_format_read_uint32(flipper_format, "CRC", &crc_temp, 1);
|
||||
instance->key2 = ((bs_temp & 0xFF) << 8) | (crc_temp & 0xFF);
|
||||
FURI_LOG_I(TAG, "Decoder deserialize: BS=0x%02lX CRC=0x%02lX key2=0x%04X", bs_temp, crc_temp, instance->key2);
|
||||
instance->key2 = ((checksum_temp & 0xFF) << 8) | (crc_temp & 0xFF);
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Decoder deserialize: Checksum=0x%02lX CRC=0x%02lX key2=0x%04X",
|
||||
checksum_temp,
|
||||
crc_temp,
|
||||
instance->key2);
|
||||
|
||||
flipper_format_read_uint32(flipper_format, "Serial", &instance->serial, 1);
|
||||
instance->generic.serial = instance->serial;
|
||||
@@ -939,18 +926,16 @@ SubGhzProtocolStatus
|
||||
flipper_format_read_uint32(flipper_format, "Cnt", &instance->count, 1);
|
||||
instance->generic.cnt = instance->count;
|
||||
|
||||
FURI_LOG_I(TAG, "Decoder deserialize: Sn=0x%08lX Btn=0x%02X Cnt=0x%05lX",
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Decoder deserialize: Sn=0x%08lX Btn=0x%02X Cnt=0x%05lX",
|
||||
(unsigned long)instance->serial,
|
||||
instance->button,
|
||||
(unsigned long)instance->count);
|
||||
|
||||
uint32_t bs_magic_temp = 0;
|
||||
if(flipper_format_read_uint32(flipper_format, "BSMagic", &bs_magic_temp, 1))
|
||||
instance->bs_magic = bs_magic_temp;
|
||||
else
|
||||
instance->bs_magic = 0x6F;
|
||||
FURI_LOG_I(TAG, "Decoder deserialize: BSMagic=0x%02X key1=%08lX%08lX",
|
||||
instance->bs_magic,
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Decoder deserialize: key1=%08lX%08lX",
|
||||
(unsigned long)(instance->key1 >> 32),
|
||||
(unsigned long)(instance->key1 & 0xFFFFFFFF));
|
||||
}
|
||||
@@ -998,6 +983,5 @@ void subghz_protocol_decoder_ford_v0_get_string(void* context, FuriString* outpu
|
||||
(unsigned long)instance->count,
|
||||
(unsigned int)display_btn,
|
||||
button_name,
|
||||
crc_ok ? "OK" : "BAD"
|
||||
);
|
||||
crc_ok ? "OK" : "BAD");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user