Skip to content

Commit

Permalink
Merge branch 'dev' into zlo/allocator-playground
Browse files Browse the repository at this point in the history
  • Loading branch information
DrZlo13 committed Apr 10, 2024
2 parents 9317a07 + fb9728d commit a40df69
Show file tree
Hide file tree
Showing 42 changed files with 1,718 additions and 130 deletions.
20 changes: 20 additions & 0 deletions applications/drivers/subghz/cc1101_ext/cc1101_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ static bool subghz_device_cc1101_ext_check_init(void) {
furi_hal_gpio_init(
subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);

// Reset GDO2 (!TX/RX) to floating state
cc1101_status = cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance);
if(cc1101_status.CHIP_RDYn != 0) {
//timeout or error
break;
}

// Go to sleep
cc1101_status = cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle);
if(cc1101_status.CHIP_RDYn != 0) {
Expand Down Expand Up @@ -385,6 +393,9 @@ void subghz_device_cc1101_ext_reset(void) {
// Warning: push pull cc1101 clock output on GD0
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance);
// Reset GDO2 (!TX/RX) to floating state
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}

Expand All @@ -394,6 +405,9 @@ void subghz_device_cc1101_ext_idle(void) {
//waiting for the chip to switch to IDLE mode
furi_check(cc1101_wait_status_state(
subghz_device_cc1101_ext->spi_bus_handle, CC1101StateIDLE, 10000));
// Reset GDO2 (!TX/RX) to floating state
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}

Expand All @@ -403,6 +417,10 @@ void subghz_device_cc1101_ext_rx(void) {
//waiting for the chip to switch to Rx mode
furi_check(
cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateRX, 10000));
// Go GDO2 (!TX/RX) to high (RX state)
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);

furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}

Expand All @@ -413,6 +431,8 @@ bool subghz_device_cc1101_ext_tx(void) {
//waiting for the chip to switch to Tx mode
furi_check(
cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateTX, 10000));
// Go GDO2 (!TX/RX) to low (TX state)
cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
return true;
}
Expand Down
21 changes: 21 additions & 0 deletions applications/main/nfc/helpers/felica_auth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "felica_auth.h"

FelicaAuthenticationContext* felica_auth_alloc() {
FelicaAuthenticationContext* instance = malloc(sizeof(FelicaAuthenticationContext));
memset(instance->card_key.data, 0, FELICA_DATA_BLOCK_SIZE);
instance->skip_auth = true;
return instance;
}

void felica_auth_free(FelicaAuthenticationContext* instance) {
furi_assert(instance);
free(instance);
}

void felica_auth_reset(FelicaAuthenticationContext* instance) {
furi_assert(instance);
memset(instance->card_key.data, 0, FELICA_DATA_BLOCK_SIZE);
instance->skip_auth = true;
instance->auth_status.external = 0;
instance->auth_status.internal = 0;
}
17 changes: 17 additions & 0 deletions applications/main/nfc/helpers/felica_auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <lib/nfc/protocols/felica/felica.h>

#ifdef __cplusplus
extern "C" {
#endif

FelicaAuthenticationContext* felica_auth_alloc();

void felica_auth_free(FelicaAuthenticationContext* instance);

void felica_auth_reset(FelicaAuthenticationContext* instance);

#ifdef __cplusplus
}
#endif
123 changes: 115 additions & 8 deletions applications/main/nfc/helpers/protocol_support/felica/felica.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

#include "../nfc_protocol_support_common.h"
#include "../nfc_protocol_support_gui_common.h"
#include "../nfc_protocol_support_unlock_helper.h"

enum {
SubmenuIndexUnlock = SubmenuIndexCommonMax,
};

static void nfc_scene_info_on_enter_felica(NfcApp* instance) {
const NfcDevice* device = instance->nfc_device;
Expand All @@ -18,6 +23,35 @@ static void nfc_scene_info_on_enter_felica(NfcApp* instance) {
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
nfc_render_felica_info(data, NfcProtocolFormatTypeFull, temp_str);

widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 48, furi_string_get_cstr(temp_str));

widget_add_button_element(
instance->widget,
GuiButtonTypeRight,
"More",
nfc_protocol_support_common_widget_callback,
instance);
furi_string_free(temp_str);
}

static bool nfc_scene_info_on_event_felica(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom && event.event == GuiButtonTypeRight) {
scene_manager_next_scene(instance->scene_manager, NfcSceneMoreInfo);
return true;
}

return false;
}

static void nfc_scene_more_info_on_enter_felica(NfcApp* instance) {
const NfcDevice* device = instance->nfc_device;
const FelicaData* data = nfc_device_get_data(device, NfcProtocolFelica);

FuriString* temp_str = furi_string_alloc();

nfc_render_felica_dump(data, temp_str);

widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 64, furi_string_get_cstr(temp_str));

Expand All @@ -29,29 +63,75 @@ static NfcCommand nfc_scene_read_poller_callback_felica(NfcGenericEvent event, v

NfcApp* instance = context;
const FelicaPollerEvent* felica_event = event.event_data;
NfcCommand command = NfcCommandContinue;

if(felica_event->type == FelicaPollerEventTypeReady) {
nfc_device_set_data(
instance->nfc_device, NfcProtocolFelica, nfc_poller_get_data(instance->poller));
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
return NfcCommandStop;
command = NfcCommandStop;
} else if(
felica_event->type == FelicaPollerEventTypeError ||
felica_event->type == FelicaPollerEventTypeIncomplete) {
nfc_device_set_data(
instance->nfc_device, NfcProtocolFelica, nfc_poller_get_data(instance->poller));
view_dispatcher_send_custom_event(
instance->view_dispatcher, NfcCustomEventPollerIncomplete);
command = NfcCommandStop;
} else if(felica_event->type == FelicaPollerEventTypeRequestAuthContext) {
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
FelicaAuthenticationContext* ctx = felica_event->data->auth_context;
ctx->skip_auth = instance->felica_auth->skip_auth;
memcpy(ctx->card_key.data, instance->felica_auth->card_key.data, FELICA_DATA_BLOCK_SIZE);
}

return NfcCommandContinue;
return command;
}

static void nfc_scene_read_on_enter_felica(NfcApp* instance) {
nfc_unlock_helper_setup_from_state(instance);
nfc_poller_start(instance->poller, nfc_scene_read_poller_callback_felica, instance);
}

bool nfc_scene_read_on_event_felica(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventCardDetected) {
nfc_unlock_helper_card_detected_handler(instance);
} else if(event.event == NfcCustomEventPollerIncomplete) {
notification_message(instance->notifications, &sequence_semi_success);
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
dolphin_deed(DolphinDeedNfcReadSuccess);
}
}
return true;
}

static void nfc_scene_read_success_on_enter_felica(NfcApp* instance) {
const NfcDevice* device = instance->nfc_device;
const FelicaData* data = nfc_device_get_data(device, NfcProtocolFelica);

FuriString* temp_str = furi_string_alloc();
furi_string_cat_printf(
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
nfc_render_felica_info(data, NfcProtocolFormatTypeShort, temp_str);

if(!scene_manager_has_previous_scene(instance->scene_manager, NfcSceneFelicaUnlockWarn)) {
furi_string_cat_printf(
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
nfc_render_felica_info(data, NfcProtocolFormatTypeShort, temp_str);
} else {
bool all_unlocked = data->blocks_read == data->blocks_total;
furi_string_cat_printf(
temp_str,
"\e#%s\n",
all_unlocked ? "All Blocks Are Unlocked" : "Some Blocks Are Locked");
nfc_render_felica_idm(data, NfcProtocolFormatTypeShort, temp_str);
uint8_t* ck_data = instance->felica_auth->card_key.data;
furi_string_cat_printf(temp_str, "Key:");
for(uint8_t i = 0; i < 7; i++) {
furi_string_cat_printf(temp_str, " %02X", ck_data[i]);
if(i == 6) furi_string_cat_printf(temp_str, "...");
}
nfc_render_felica_blocks_count(data, temp_str, false);
}
felica_auth_reset(instance->felica_auth);

widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str));
Expand All @@ -74,23 +154,50 @@ static void nfc_scene_emulate_on_enter_felica(NfcApp* instance) {
nfc_listener_start(instance->listener, NULL, NULL);
}

static void nfc_scene_read_menu_on_enter_felica(NfcApp* instance) {
const FelicaData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolFelica);
if(data->blocks_read != data->blocks_total) {
submenu_add_item(
instance->submenu,
"Unlock",
SubmenuIndexUnlock,
nfc_protocol_support_common_submenu_callback,
instance);
}
}

static bool nfc_scene_read_menu_on_event_felica(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexUnlock) {
scene_manager_next_scene(instance->scene_manager, NfcSceneFelicaKeyInput);
return true;
}
}
return false;
}

const NfcProtocolSupportBase nfc_protocol_support_felica = {
.features = NfcProtocolFeatureEmulateUid,

.scene_info =
{
.on_enter = nfc_scene_info_on_enter_felica,
.on_event = nfc_scene_info_on_event_felica,
},
.scene_more_info =
{
.on_enter = nfc_scene_more_info_on_enter_felica,
.on_event = nfc_protocol_support_common_on_event_empty,
},
.scene_read =
{
.on_enter = nfc_scene_read_on_enter_felica,
.on_event = nfc_protocol_support_common_on_event_empty,
.on_event = nfc_scene_read_on_event_felica,
},
.scene_read_menu =
{
.on_enter = nfc_protocol_support_common_on_enter_empty,
.on_event = nfc_protocol_support_common_on_event_empty,
.on_enter = nfc_scene_read_menu_on_enter_felica,
.on_event = nfc_scene_read_menu_on_event_felica,
},
.scene_read_success =
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,107 @@
#include "felica_render.h"

void nfc_render_felica_info(
void nfc_render_felica_blocks_count(
const FelicaData* data,
FuriString* str,
bool render_auth_notification) {
furi_string_cat_printf(str, "\nBlocks Read: %u/%u", data->blocks_read, data->blocks_total);
if(render_auth_notification && data->blocks_read != data->blocks_total) {
furi_string_cat_printf(str, "\nAuth-protected blocks!");
}
}

void nfc_render_felica_idm(
const FelicaData* data,
NfcProtocolFormatType format_type,
FuriString* str) {
furi_string_cat_printf(str, "IDm:");
furi_string_cat_printf(str, (format_type == NfcProtocolFormatTypeFull) ? "IDm:\n" : "IDm:");

for(size_t i = 0; i < FELICA_IDM_SIZE; i++) {
furi_string_cat_printf(str, " %02X", data->idm.data[i]);
furi_string_cat_printf(
str,
(format_type == NfcProtocolFormatTypeFull) ? "%02X " : " %02X",
data->idm.data[i]);
}
}

void nfc_render_felica_info(
const FelicaData* data,
NfcProtocolFormatType format_type,
FuriString* str) {
if(format_type == NfcProtocolFormatTypeFull) {
furi_string_cat_printf(str, "Tech: JIS X 6319-4,\nISO 18092 [NFC-F]\n");
}

nfc_render_felica_idm(data, format_type, str);

if(format_type == NfcProtocolFormatTypeFull) {
furi_string_cat_printf(str, "\nPMm:");
furi_string_cat_printf(str, "\nPMm:\n");
for(size_t i = 0; i < FELICA_PMM_SIZE; ++i) {
furi_string_cat_printf(str, " %02X", data->pmm.data[i]);
furi_string_cat_printf(str, "%02X ", data->pmm.data[i]);
}
}
nfc_render_felica_blocks_count(data, str, true);
}

static void nfc_render_felica_block_name(
const char* name,
FuriString* str,
uint8_t prefix_separator_cnt,
uint8_t suffix_separator_cnt) {
for(uint8_t i = 0; i < prefix_separator_cnt; i++) {
furi_string_cat_printf(str, ":");
}
furi_string_cat_printf(str, "[ %s ]", name);
for(uint8_t i = 0; i < suffix_separator_cnt; i++) {
furi_string_cat_printf(str, ":");
}
}

static void nfc_render_felica_block_data(const FelicaBlock* block, FuriString* str) {
furi_string_cat_printf(str, "\nSF1=%02X; SF2=%02X\n", block->SF1, block->SF2);
for(size_t j = 0; j < FELICA_DATA_BLOCK_SIZE; j++) {
if((j != 0) && (j % 8 == 0)) furi_string_cat_printf(str, "\n");
furi_string_cat_printf(str, "%02X ", block->data[j]);
}
furi_string_cat_printf(str, "\n");
}

static void nfc_render_felica_block(
const FelicaBlock* block,
FuriString* str,
const char* name,
uint8_t prefix_separator_cnt,
uint8_t suffix_separator_cnt) {
nfc_render_felica_block_name(name, str, prefix_separator_cnt, suffix_separator_cnt);
nfc_render_felica_block_data(block, str);
}

void nfc_render_felica_dump(const FelicaData* data, FuriString* str) {
FuriString* name = furi_string_alloc();
for(size_t i = 0; i < 14; i++) {
furi_string_printf(name, "S_PAD%d", i);
uint8_t suf_cnt = 18;
if(i == 1) {
suf_cnt = 19;
} else if((i == 10) || (i == 12) || (i == 13)) {
suf_cnt = 16;
}
nfc_render_felica_block(
&data->data.fs.spad[i], str, furi_string_get_cstr(name), 20, suf_cnt);
}
furi_string_free(name);
nfc_render_felica_block(&data->data.fs.reg, str, "REG", 23, 23);
nfc_render_felica_block(&data->data.fs.rc, str, "RC", 25, 25);
nfc_render_felica_block(&data->data.fs.mac, str, "MAC", 23, 23);
nfc_render_felica_block(&data->data.fs.id, str, "ID", 25, 25);
nfc_render_felica_block(&data->data.fs.d_id, str, "D_ID", 22, 24);
nfc_render_felica_block(&data->data.fs.ser_c, str, "SER_C", 20, 21);
nfc_render_felica_block(&data->data.fs.sys_c, str, "SYS_C", 20, 21);
nfc_render_felica_block(&data->data.fs.ckv, str, "CKV", 23, 23);
nfc_render_felica_block(&data->data.fs.ck, str, "CK", 25, 25);
nfc_render_felica_block(&data->data.fs.mc, str, "MC", 25, 24);
nfc_render_felica_block(&data->data.fs.wcnt, str, "WCNT", 22, 20);
nfc_render_felica_block(&data->data.fs.mac_a, str, "MAC_A", 20, 20);
nfc_render_felica_block(&data->data.fs.state, str, "STATE", 20, 21);
nfc_render_felica_block(&data->data.fs.crc_check, str, "CRC_CHCK", 15, 17);
}
Loading

0 comments on commit a40df69

Please sign in to comment.