mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-27 15:00:46 +00:00
Merge branch 'Eng1n33r:dev' into subbrute-rev3
This commit is contained in:
commit
9ba7e625ca
8 changed files with 144 additions and 8 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
#define FLIPPER_LCD_WIDTH 128
|
||||
#define FLIPPER_LCD_HEIGHT 64
|
||||
#define MAX_SPEED 3
|
||||
|
||||
typedef enum { EventTypeTick, EventTypeKey } EventType;
|
||||
|
||||
|
@ -51,6 +52,7 @@ typedef struct {
|
|||
unsigned int brickCount; //Amount of bricks hit
|
||||
int tick; //Tick counter
|
||||
bool gameStarted; // Did the game start?
|
||||
int speed; // Ball speed
|
||||
} ArkanoidState;
|
||||
|
||||
typedef struct {
|
||||
|
@ -72,12 +74,18 @@ int rand_range(int min, int max) {
|
|||
|
||||
void move_ball(Canvas* canvas, ArkanoidState* st) {
|
||||
st->tick++;
|
||||
|
||||
int current_speed = abs(st->speed-1 - MAX_SPEED);
|
||||
if (st->tick % current_speed != 0 && st->tick % (current_speed + 1) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(st->ball_state.released) {
|
||||
//Move ball
|
||||
if(abs(st->ball_state.dx) == 2) {
|
||||
st->ball_state.xb += st->ball_state.dx / 2;
|
||||
// 2x speed is really 1.5 speed
|
||||
if(st->tick % 2 == 0) st->ball_state.xb += st->ball_state.dx / 2;
|
||||
if((st->tick / current_speed) % 2 == 0) st->ball_state.xb += st->ball_state.dx / 2;
|
||||
} else {
|
||||
st->ball_state.xb += st->ball_state.dx;
|
||||
}
|
||||
|
@ -286,6 +294,7 @@ static void arkanoid_state_init(ArkanoidState* arkanoid_state) {
|
|||
arkanoid_state->ROWS = 4;
|
||||
arkanoid_state->ball_state.dx = -1;
|
||||
arkanoid_state->ball_state.dy = -1;
|
||||
arkanoid_state->speed = 2;
|
||||
arkanoid_state->bounced = false;
|
||||
arkanoid_state->lives = 3;
|
||||
arkanoid_state->level = 1;
|
||||
|
@ -414,8 +423,14 @@ int32_t arkanoid_game_app(void* p) {
|
|||
}
|
||||
break;
|
||||
case InputKeyUp:
|
||||
if(arkanoid_state->speed < MAX_SPEED) {
|
||||
arkanoid_state->speed++;
|
||||
}
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(arkanoid_state->speed > 1) {
|
||||
arkanoid_state->speed--;
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(arkanoid_state->gameStarted == false) {
|
||||
|
|
|
@ -248,12 +248,16 @@ static void music_player_worker_callback(
|
|||
view_port_update(music_player->view_port);
|
||||
}
|
||||
|
||||
void music_player_clear(MusicPlayer* instance) {
|
||||
memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE);
|
||||
memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE);
|
||||
music_player_worker_clear(instance->worker);
|
||||
}
|
||||
|
||||
MusicPlayer* music_player_alloc() {
|
||||
MusicPlayer* instance = malloc(sizeof(MusicPlayer));
|
||||
|
||||
instance->model = malloc(sizeof(MusicPlayerModel));
|
||||
memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE);
|
||||
memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE);
|
||||
instance->model->volume = 3;
|
||||
|
||||
instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
|
@ -265,6 +269,8 @@ MusicPlayer* music_player_alloc() {
|
|||
instance->worker, MUSIC_PLAYER_VOLUMES[instance->model->volume]);
|
||||
music_player_worker_set_callback(instance->worker, music_player_worker_callback, instance);
|
||||
|
||||
music_player_clear(instance);
|
||||
|
||||
instance->view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(instance->view_port, render_callback, instance);
|
||||
view_port_input_callback_set(instance->view_port, input_callback, instance);
|
||||
|
@ -299,7 +305,7 @@ int32_t music_player_app(void* p) {
|
|||
|
||||
do {
|
||||
if(p && strlen(p)) {
|
||||
furi_string_cat(file_path, (const char*)p);
|
||||
furi_string_set(file_path, (const char*)p);
|
||||
} else {
|
||||
furi_string_set(file_path, MUSIC_PLAYER_APP_PATH_FOLDER);
|
||||
|
||||
|
@ -350,7 +356,9 @@ int32_t music_player_app(void* p) {
|
|||
}
|
||||
|
||||
music_player_worker_stop(music_player->worker);
|
||||
} while(0);
|
||||
if(p && strlen(p)) break; // Exit instead of going to browser if launched with arg
|
||||
music_player_clear(music_player);
|
||||
} while(1);
|
||||
|
||||
furi_string_free(file_path);
|
||||
music_player_free(music_player);
|
||||
|
|
|
@ -108,6 +108,10 @@ MusicPlayerWorker* music_player_worker_alloc() {
|
|||
return instance;
|
||||
}
|
||||
|
||||
void music_player_worker_clear(MusicPlayerWorker* instance) {
|
||||
NoteBlockArray_reset(instance->notes);
|
||||
}
|
||||
|
||||
void music_player_worker_free(MusicPlayerWorker* instance) {
|
||||
furi_assert(instance);
|
||||
furi_thread_free(instance->thread);
|
||||
|
@ -129,6 +133,7 @@ static bool is_space(const char c) {
|
|||
|
||||
static size_t extract_number(const char* string, uint32_t* number) {
|
||||
size_t ret = 0;
|
||||
*number = 0;
|
||||
while(is_digit(*string)) {
|
||||
*number *= 10;
|
||||
*number += (*string - '0');
|
||||
|
@ -140,6 +145,7 @@ static size_t extract_number(const char* string, uint32_t* number) {
|
|||
|
||||
static size_t extract_dots(const char* string, uint32_t* number) {
|
||||
size_t ret = 0;
|
||||
*number = 0;
|
||||
while(*string == '.') {
|
||||
*number += 1;
|
||||
string++;
|
||||
|
|
|
@ -18,6 +18,8 @@ typedef struct MusicPlayerWorker MusicPlayerWorker;
|
|||
|
||||
MusicPlayerWorker* music_player_worker_alloc();
|
||||
|
||||
void music_player_worker_clear(MusicPlayerWorker* instance);
|
||||
|
||||
void music_player_worker_free(MusicPlayerWorker* instance);
|
||||
|
||||
bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path);
|
||||
|
|
|
@ -57,7 +57,6 @@ static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) {
|
|||
furi_string_set(obj->path, src->path);
|
||||
furi_string_set(obj->display_name, src->display_name);
|
||||
if(src->custom_icon_data) {
|
||||
obj->custom_icon_data = malloc(CUSTOM_ICON_MAX_SIZE);
|
||||
memcpy(obj->custom_icon_data, src->custom_icon_data, CUSTOM_ICON_MAX_SIZE);
|
||||
} else {
|
||||
obj->custom_icon_data = NULL;
|
||||
|
@ -379,6 +378,9 @@ static void
|
|||
});
|
||||
furi_string_free(item.display_name);
|
||||
furi_string_free(item.path);
|
||||
if(item.custom_icon_data) {
|
||||
free(item.custom_icon_data);
|
||||
}
|
||||
} else {
|
||||
with_view_model(
|
||||
browser->view, (FileBrowserModel * model) {
|
||||
|
|
|
@ -452,6 +452,10 @@ static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) {
|
|||
section_header->sh_size;
|
||||
}
|
||||
|
||||
static bool str_prefix(const char* str, const char* prefix) {
|
||||
return strncmp(prefix, str, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
static bool elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) {
|
||||
if(section_header->sh_size == 0) {
|
||||
FURI_LOG_D(TAG, "No data for section");
|
||||
|
@ -485,6 +489,43 @@ static SectionType elf_preload_section(
|
|||
FlipperApplicationManifest* manifest) {
|
||||
const char* name = furi_string_get_cstr(name_string);
|
||||
|
||||
#ifdef ELF_DEBUG_LOG
|
||||
// log section name, type and flags
|
||||
FuriString* flags_string = furi_string_alloc();
|
||||
if(section_header->sh_flags & SHF_WRITE) furi_string_cat(flags_string, "W");
|
||||
if(section_header->sh_flags & SHF_ALLOC) furi_string_cat(flags_string, "A");
|
||||
if(section_header->sh_flags & SHF_EXECINSTR) furi_string_cat(flags_string, "X");
|
||||
if(section_header->sh_flags & SHF_MERGE) furi_string_cat(flags_string, "M");
|
||||
if(section_header->sh_flags & SHF_STRINGS) furi_string_cat(flags_string, "S");
|
||||
if(section_header->sh_flags & SHF_INFO_LINK) furi_string_cat(flags_string, "I");
|
||||
if(section_header->sh_flags & SHF_LINK_ORDER) furi_string_cat(flags_string, "L");
|
||||
if(section_header->sh_flags & SHF_OS_NONCONFORMING) furi_string_cat(flags_string, "O");
|
||||
if(section_header->sh_flags & SHF_GROUP) furi_string_cat(flags_string, "G");
|
||||
if(section_header->sh_flags & SHF_TLS) furi_string_cat(flags_string, "T");
|
||||
if(section_header->sh_flags & SHF_COMPRESSED) furi_string_cat(flags_string, "T");
|
||||
if(section_header->sh_flags & SHF_MASKOS) furi_string_cat(flags_string, "o");
|
||||
if(section_header->sh_flags & SHF_MASKPROC) furi_string_cat(flags_string, "p");
|
||||
if(section_header->sh_flags & SHF_ORDERED) furi_string_cat(flags_string, "R");
|
||||
if(section_header->sh_flags & SHF_EXCLUDE) furi_string_cat(flags_string, "E");
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Section %s: type: %ld, flags: %s",
|
||||
name,
|
||||
section_header->sh_type,
|
||||
furi_string_get_cstr(flags_string));
|
||||
furi_string_free(flags_string);
|
||||
#endif
|
||||
|
||||
// ignore .ARM and .rel.ARM sections
|
||||
// TODO: how to do it not by name?
|
||||
// .ARM: type 0x70000001, flags SHF_ALLOC | SHF_LINK_ORDER
|
||||
// .rel.ARM: type 0x9, flags SHT_REL
|
||||
if(str_prefix(name, ".ARM") || str_prefix(name, ".rel.ARM")) {
|
||||
FURI_LOG_D(TAG, "Ignoring ARM section");
|
||||
return SectionTypeUnused;
|
||||
}
|
||||
|
||||
// Load allocable section
|
||||
if(section_header->sh_flags & SHF_ALLOC) {
|
||||
ELFSection* section_p = elf_file_get_or_put_section(elf, name);
|
||||
|
|
|
@ -69,9 +69,18 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) {
|
|||
FuriString* next_line;
|
||||
next_line = furi_string_alloc();
|
||||
while(true) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(!stream_read_line(dict->stream, next_line)) {
|
||||
FURI_LOG_T(TAG, "No keys left in dict");
|
||||
break;
|
||||
}
|
||||
furi_string_trim(next_line);
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"Read line: %s, len: %d",
|
||||
furi_string_get_cstr(next_line),
|
||||
furi_string_size(next_line));
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN - 1) continue;
|
||||
dict->total_keys++;
|
||||
}
|
||||
furi_string_free(next_line);
|
||||
|
|
|
@ -453,6 +453,54 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) {
|
|||
}
|
||||
}
|
||||
|
||||
static void nfc_worker_mf_classic_key_attack(
|
||||
NfcWorker* nfc_worker,
|
||||
uint64_t key,
|
||||
FuriHalNfcTxRxContext* tx_rx,
|
||||
uint16_t start_sector) {
|
||||
furi_assert(nfc_worker);
|
||||
|
||||
MfClassicData* data = &nfc_worker->dev_data->mf_classic_data;
|
||||
uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type);
|
||||
|
||||
furi_assert(start_sector < total_sectors);
|
||||
|
||||
// Check every sector's A and B keys with the given key
|
||||
for(size_t i = start_sector; i < total_sectors; i++) {
|
||||
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
||||
if(mf_classic_is_sector_read(data, i)) continue;
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"Trying A key for sector %d, key: %04lx%08lx",
|
||||
i,
|
||||
(uint32_t)(key >> 32),
|
||||
(uint32_t)key);
|
||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"Trying B key for sector %d, key: %04lx%08lx",
|
||||
i,
|
||||
(uint32_t)(key >> 32),
|
||||
(uint32_t)key);
|
||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
if(mf_classic_is_sector_read(data, i)) continue;
|
||||
mf_classic_read_sector(tx_rx, data, i);
|
||||
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
furi_assert(nfc_worker);
|
||||
furi_assert(nfc_worker->callback);
|
||||
|
@ -485,6 +533,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
|||
bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
uint16_t key_index = 0;
|
||||
while(mf_classic_dict_get_next_key(dict, &key)) {
|
||||
FURI_LOG_T(TAG, "Key %d", key_index);
|
||||
if(++key_index % NFC_DICT_KEY_BATCH_SIZE == 0) {
|
||||
nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context);
|
||||
}
|
||||
|
@ -506,15 +555,19 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
|||
is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA);
|
||||
if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyA)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
||||
}
|
||||
furi_hal_nfc_sleep();
|
||||
}
|
||||
if(!is_key_b_found) {
|
||||
is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyB)) {
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
||||
}
|
||||
}
|
||||
if(is_key_a_found && is_key_b_found) break;
|
||||
|
|
Loading…
Reference in a new issue