mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-01 22:08:55 -07:00
Merge branch 'Eng1n33r:dev' into feat/playlist
This commit is contained in:
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
# Visual Studio Code workspace for Flipper Zero
|
||||
|
||||
## Setup
|
||||
|
||||
* To start developing with VSCode, run `./fbt vscode_dist` in project root. _That should only be done once_
|
||||
* After that, open firmware folder in VSCode: "File" > "Open folder"
|
||||
|
||||
For more details on fbt, see [fbt docs](../documentation/fbt.md).
|
||||
|
||||
|
||||
## Workflow
|
||||
|
||||
Commands for building firmware are invoked through Build menu: Ctrl+Shift+B.
|
||||
|
||||
To attach a debugging session, first build and flash firmware, then choose your debug probe in Debug menu (Ctrl+Shift+D).
|
||||
|
||||
Note that you have to detach debugging session before rebuilding and re-flashing firmware.
|
||||
Vendored
+2
-2
@@ -55,13 +55,13 @@
|
||||
"label": "[Release] Build update bundle",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt update_package COMPACT=1 DEBUG=0"
|
||||
"command": "./fbt updater_package COMPACT=1 DEBUG=0"
|
||||
},
|
||||
{
|
||||
"label": "[Debug] Build update bundle",
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"command": "./fbt update_package"
|
||||
"command": "./fbt updater_package"
|
||||
},
|
||||
{
|
||||
"label": "[Release] Build updater",
|
||||
|
||||
+6
-4
@@ -1,8 +1,10 @@
|
||||
### New changes
|
||||
* Universal Remote for ACs - New buttons and updated asset - see PR #45 & commit `ef7dcc`
|
||||
* BadUSB fix crash when executing file from Archive app
|
||||
* Dec/Hex Converter plugin - [by theisolinearchip](https://github.com/theisolinearchip)
|
||||
* SubGHz frequencies sorted by setting them by default via `setting_user` file
|
||||
* Not replace keeloq mfcodes user file on every update
|
||||
* Universal Remote for ACs - New button icon and updated asset by Svarich
|
||||
* BadUSB proper fix from OFW PR 1525
|
||||
* NRF24 Sniffer - Fixed an issue where attempts to write to addresses.txt freezes app if the file doesn't exist - by ESurge - PR #46
|
||||
* OFW: Mifare Classic emulation fixes
|
||||
* OFW: Storage fixes for handling empty files
|
||||
|
||||
**Note: Prefer installing using web updater or by self update package, all needed assets will be installed**
|
||||
|
||||
|
||||
@@ -102,7 +102,9 @@ BadUsbApp* bad_usb_app_alloc(char* arg) {
|
||||
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
|
||||
} else {
|
||||
if(!string_empty_p(app->file_path)) {
|
||||
scene_manager_next_scene(app->scene_manager, BadUsbScenePWork);
|
||||
app->bad_usb_script = bad_usb_script_open(app->file_path);
|
||||
bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout);
|
||||
scene_manager_next_scene(app->scene_manager, BadUsbSceneWork);
|
||||
} else {
|
||||
string_set_str(app->file_path, BAD_USB_APP_BASE_FOLDER);
|
||||
scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect);
|
||||
@@ -122,7 +124,6 @@ void bad_usb_app_free(BadUsbApp* app) {
|
||||
|
||||
// Views
|
||||
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWork);
|
||||
|
||||
bad_usb_free(app->bad_usb_view);
|
||||
|
||||
// Custom Widget
|
||||
@@ -157,4 +158,4 @@ int32_t bad_usb_app(void* p) {
|
||||
|
||||
bad_usb_app_free(bad_usb_app);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,7 +662,3 @@ BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb) {
|
||||
furi_assert(bad_usb);
|
||||
return &(bad_usb->st);
|
||||
}
|
||||
|
||||
void bad_usb_script_set_run_state(BadUsbState* st, bool run) {
|
||||
st->run_from_p = run;
|
||||
}
|
||||
@@ -22,7 +22,6 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
BadUsbWorkerState state;
|
||||
bool run_from_p;
|
||||
uint16_t line_cur;
|
||||
uint16_t line_nb;
|
||||
uint32_t delay_remain;
|
||||
@@ -43,8 +42,6 @@ void bad_usb_script_toggle(BadUsbScript* bad_usb);
|
||||
|
||||
BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb);
|
||||
|
||||
void bad_usb_script_set_run_state(BadUsbState* st, bool run);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
ADD_SCENE(bad_usb, file_select, FileSelect)
|
||||
ADD_SCENE(bad_usb, work, Work)
|
||||
ADD_SCENE(bad_usb, pwork, PWork)
|
||||
ADD_SCENE(bad_usb, error, Error)
|
||||
ADD_SCENE(bad_usb, config, Config)
|
||||
ADD_SCENE(bad_usb, config_layout, ConfigLayout)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "../bad_usb_script.h"
|
||||
#include "../bad_usb_app_i.h"
|
||||
#include "../views/bad_usb_view.h"
|
||||
#include "furi_hal.h"
|
||||
#include "m-string.h"
|
||||
#include "toolbox/path.h"
|
||||
|
||||
void bad_usb_scene_pwork_button_callback(InputKey key, void* context) {
|
||||
furi_assert(context);
|
||||
BadUsbApp* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, key);
|
||||
}
|
||||
|
||||
bool bad_usb_scene_pwork_on_event(void* context, SceneManagerEvent event) {
|
||||
BadUsbApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == InputKeyOk) {
|
||||
bad_usb_script_toggle(app->bad_usb_script);
|
||||
consumed = true;
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeTick) {
|
||||
bad_usb_set_state(app->bad_usb_view, bad_usb_script_get_state(app->bad_usb_script));
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void bad_usb_scene_pwork_on_enter(void* context) {
|
||||
BadUsbApp* app = context;
|
||||
|
||||
string_t file_name;
|
||||
string_init(file_name);
|
||||
|
||||
path_extract_filename(app->file_path, file_name, true);
|
||||
bad_usb_set_file_name(app->bad_usb_view, string_get_cstr(file_name));
|
||||
app->bad_usb_script = bad_usb_script_open(app->file_path);
|
||||
|
||||
bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout);
|
||||
|
||||
string_t layout;
|
||||
string_init(layout);
|
||||
path_extract_filename(app->keyboard_layout, layout, true);
|
||||
bad_usb_set_layout(app->bad_usb_view, string_get_cstr(layout));
|
||||
string_clear(layout);
|
||||
|
||||
string_clear(file_name);
|
||||
|
||||
bad_usb_set_state(app->bad_usb_view, bad_usb_script_get_state(app->bad_usb_script));
|
||||
|
||||
// set app state - is executed from archive app
|
||||
bad_usb_script_set_run_state(bad_usb_script_get_state(app->bad_usb_script), true);
|
||||
|
||||
bad_usb_set_button_callback(app->bad_usb_view, bad_usb_scene_pwork_button_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, BadUsbAppViewWork);
|
||||
}
|
||||
|
||||
void bad_usb_scene_pwork_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
//BadUsbApp* app = context;
|
||||
//bad_usb_script_close(app->bad_usb_script);
|
||||
}
|
||||
@@ -46,9 +46,6 @@ void bad_usb_scene_work_on_enter(void* context) {
|
||||
|
||||
bad_usb_set_state(app->bad_usb_view, bad_usb_script_get_state(app->bad_usb_script));
|
||||
|
||||
// set app state - is executed from archive app
|
||||
bad_usb_script_set_run_state(bad_usb_script_get_state(app->bad_usb_script), false);
|
||||
|
||||
bad_usb_set_button_callback(app->bad_usb_view, bad_usb_scene_work_button_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, BadUsbAppViewWork);
|
||||
}
|
||||
|
||||
@@ -49,9 +49,8 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
|
||||
elements_button_center(canvas, "Stop");
|
||||
}
|
||||
|
||||
if(((model->state.state == BadUsbStateNotConnected) ||
|
||||
(model->state.state == BadUsbStateIdle) || (model->state.state == BadUsbStateDone)) &&
|
||||
!model->state.run_from_p) {
|
||||
if((model->state.state == BadUsbStateNotConnected) ||
|
||||
(model->state.state == BadUsbStateIdle) || (model->state.state == BadUsbStateDone)) {
|
||||
elements_button_left(canvas, "Config");
|
||||
}
|
||||
|
||||
@@ -189,7 +188,6 @@ void bad_usb_set_layout(BadUsb* bad_usb, const char* layout) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) {
|
||||
furi_assert(st);
|
||||
with_view_model(
|
||||
@@ -198,4 +196,4 @@ void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) {
|
||||
model->anim_frame ^= 1;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ void infrared_scene_universal_ac_on_enter(void* context) {
|
||||
0,
|
||||
36,
|
||||
24,
|
||||
&I_Up_25x27,
|
||||
&I_Up_hvr_25x27,
|
||||
&I_Mode_25x27,
|
||||
&I_Mode_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "MODE");
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
#include <furi_hal.h>
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <stdlib.h>
|
||||
#include <furi_hal_gpio.h>
|
||||
#include <furi_hal_spi.h>
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
|
||||
#include <nrf24.h>
|
||||
#include <toolbox/stream/file_stream.h>
|
||||
|
||||
@@ -156,7 +154,11 @@ static void hexlify(uint8_t* in, uint8_t size, char* out) {
|
||||
snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]);
|
||||
}
|
||||
|
||||
static bool save_addr_to_file(Storage* storage, uint8_t* data, uint8_t size) {
|
||||
static bool save_addr_to_file(
|
||||
Storage* storage,
|
||||
uint8_t* data,
|
||||
uint8_t size,
|
||||
NotificationApp* notification) {
|
||||
size_t file_size = 0;
|
||||
uint8_t linesize = 0;
|
||||
char filepath[42] = {0};
|
||||
@@ -177,7 +179,7 @@ static bool save_addr_to_file(Storage* storage, uint8_t* data, uint8_t size) {
|
||||
stream_seek(stream, 0, StreamOffsetFromStart);
|
||||
|
||||
// check if address already exists in file
|
||||
if(file_stream_open(stream, filepath, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
if(file_stream_open(stream, filepath, FSAM_READ_WRITE, FSOM_OPEN_APPEND)) {
|
||||
bool found = false;
|
||||
file_size = stream_size(stream);
|
||||
stream_seek(stream, 0, StreamOffsetFromStart);
|
||||
@@ -197,22 +199,31 @@ static bool save_addr_to_file(Storage* storage, uint8_t* data, uint8_t size) {
|
||||
}
|
||||
free(file_contents);
|
||||
}
|
||||
stream_free(stream);
|
||||
if(found) return false;
|
||||
|
||||
stream = file_stream_alloc(storage);
|
||||
stream_seek(stream, 0, StreamOffsetFromStart);
|
||||
}
|
||||
if(found) {
|
||||
FURI_LOG_I(TAG, "Address exists in file. Ending save process.");
|
||||
stream_free(stream);
|
||||
return false;
|
||||
} else {
|
||||
if(stream_write(stream, (uint8_t*)addrline, linesize) != linesize) {
|
||||
FURI_LOG_I(TAG, "Failed to write bytes to file stream.");
|
||||
stream_free(stream);
|
||||
return false;
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "Found a new address: %s", addrline);
|
||||
FURI_LOG_I(TAG, "Save successful!");
|
||||
|
||||
// save address to file
|
||||
if(!file_stream_open(stream, filepath, FSAM_WRITE, FSOM_OPEN_APPEND))
|
||||
notification_message(notification, &sequence_success);
|
||||
|
||||
stream_free(stream);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "Cannot open file \"%s\"", filepath);
|
||||
if(stream_write(stream, (uint8_t*)addrline, linesize) != linesize)
|
||||
FURI_LOG_I(TAG, "failed to write bytes to file stream");
|
||||
|
||||
FURI_LOG_I(TAG, "save successful");
|
||||
stream_free(stream);
|
||||
return true;
|
||||
stream_free(stream);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void alt_address(uint8_t* addr, uint8_t* altaddr) {
|
||||
@@ -244,7 +255,7 @@ void alt_address(uint8_t* addr, uint8_t* altaddr) {
|
||||
for(int i = 0; i < 5; i++) altaddr[i] = tmpaddr[4 - i];
|
||||
}
|
||||
|
||||
static void wrap_up(Storage* storage) {
|
||||
static void wrap_up(Storage* storage, NotificationApp* notification) {
|
||||
uint8_t ch;
|
||||
uint8_t addr[5];
|
||||
uint8_t altaddr[5];
|
||||
@@ -277,7 +288,7 @@ static void wrap_up(Storage* storage) {
|
||||
|
||||
if(ch <= LOGITECH_MAX_CHANNEL) {
|
||||
hexlify(addr, 5, top_address);
|
||||
save_addr_to_file(storage, addr, 5);
|
||||
save_addr_to_file(storage, addr, 5, notification);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -311,10 +322,13 @@ int32_t nrfsniff_app(void* p) {
|
||||
view_port_input_callback_set(view_port, input_callback, event_queue);
|
||||
|
||||
// Open GUI and register view_port
|
||||
Gui* gui = furi_record_open("gui");
|
||||
Gui* gui = furi_record_open(RECORD_GUI);
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
Storage* storage = furi_record_open("storage");
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
storage_common_mkdir(storage, NRFSNIFF_APP_PATH_FOLDER);
|
||||
|
||||
PluginEvent event;
|
||||
@@ -364,7 +378,7 @@ int32_t nrfsniff_app(void* p) {
|
||||
start_sniffing();
|
||||
start = furi_get_tick();
|
||||
} else
|
||||
wrap_up(storage);
|
||||
wrap_up(storage, notification);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
if(event.input.type == InputTypeLong) processing = false;
|
||||
@@ -392,7 +406,7 @@ int32_t nrfsniff_app(void* p) {
|
||||
}
|
||||
|
||||
if(furi_get_tick() - start >= SAMPLE_TIME) {
|
||||
wrap_up(storage);
|
||||
wrap_up(storage, notification);
|
||||
target_channel++;
|
||||
if(target_channel > LOGITECH_MAX_CHANNEL) target_channel = 2;
|
||||
|
||||
@@ -408,8 +422,10 @@ int32_t nrfsniff_app(void* p) {
|
||||
furi_hal_spi_release(nrf24_HANDLE);
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close("gui");
|
||||
furi_record_close("storage");
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
|
||||
|
||||
@@ -305,21 +305,27 @@ static void rpc_system_storage_read_process(const PB_Main* request, void* contex
|
||||
response->command_id = request->command_id;
|
||||
response->which_content = PB_Main_storage_read_response_tag;
|
||||
response->command_status = PB_CommandStatus_OK;
|
||||
response->content.storage_read_response.has_file = true;
|
||||
response->content.storage_read_response.file.data =
|
||||
malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(MIN(size_left, MAX_DATA_SIZE)));
|
||||
uint8_t* buffer = response->content.storage_read_response.file.data->bytes;
|
||||
uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
|
||||
|
||||
size_t read_size = MIN(size_left, MAX_DATA_SIZE);
|
||||
*read_size_msg = storage_file_read(file, buffer, read_size);
|
||||
size_left -= read_size;
|
||||
result = (*read_size_msg == read_size);
|
||||
if(read_size) {
|
||||
response->content.storage_read_response.has_file = true;
|
||||
response->content.storage_read_response.file.data =
|
||||
malloc(PB_BYTES_ARRAY_T_ALLOCSIZE());
|
||||
uint8_t* buffer = response->content.storage_read_response.file.data->bytes;
|
||||
uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
|
||||
|
||||
if(result) {
|
||||
response->has_next = (size_left > 0);
|
||||
rpc_send_and_release(session, response);
|
||||
*read_size_msg = storage_file_read(file, buffer, read_size);
|
||||
size_left -= read_size;
|
||||
result = (*read_size_msg == read_size);
|
||||
|
||||
response->has_next = result && (size_left > 0);
|
||||
} else {
|
||||
response->content.storage_read_response.has_file = false;
|
||||
response->has_next = false;
|
||||
result = true;
|
||||
}
|
||||
|
||||
rpc_send_and_release(session, response);
|
||||
} while((size_left != 0) && result);
|
||||
|
||||
if(!result) {
|
||||
@@ -349,7 +355,7 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
|
||||
RpcSession* session = rpc_storage->session;
|
||||
furi_assert(session);
|
||||
|
||||
bool result = true;
|
||||
bool fs_operation_success = true;
|
||||
|
||||
if(!path_contains_only_ascii(request->content.storage_write_request.path)) {
|
||||
rpc_storage->current_command_id = request->command_id;
|
||||
@@ -370,28 +376,32 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
|
||||
rpc_storage->current_command_id = request->command_id;
|
||||
rpc_storage->state = RpcStorageStateWriting;
|
||||
const char* path = request->content.storage_write_request.path;
|
||||
result = storage_file_open(rpc_storage->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
|
||||
fs_operation_success =
|
||||
storage_file_open(rpc_storage->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
|
||||
}
|
||||
|
||||
File* file = rpc_storage->file;
|
||||
bool send_response = false;
|
||||
|
||||
if(result) {
|
||||
uint8_t* buffer = request->content.storage_write_request.file.data->bytes;
|
||||
size_t buffer_size = request->content.storage_write_request.file.data->size;
|
||||
|
||||
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
||||
result = (written_size == buffer_size);
|
||||
|
||||
if(result && !request->has_next) {
|
||||
rpc_send_and_release_empty(
|
||||
session, rpc_storage->current_command_id, PB_CommandStatus_OK);
|
||||
rpc_system_storage_reset_state(rpc_storage, session, false);
|
||||
if(fs_operation_success) {
|
||||
if(request->content.storage_write_request.has_file) {
|
||||
uint8_t* buffer = request->content.storage_write_request.file.data->bytes;
|
||||
size_t buffer_size = request->content.storage_write_request.file.data->size;
|
||||
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
||||
fs_operation_success = (written_size == buffer_size);
|
||||
}
|
||||
|
||||
send_response = !request->has_next;
|
||||
}
|
||||
|
||||
if(!result) {
|
||||
rpc_send_and_release_empty(
|
||||
session, rpc_storage->current_command_id, rpc_system_storage_get_file_error(file));
|
||||
PB_CommandStatus command_status = PB_CommandStatus_OK;
|
||||
if(!fs_operation_success) {
|
||||
send_response = true;
|
||||
command_status = rpc_system_storage_get_file_error(file);
|
||||
}
|
||||
|
||||
if(send_response) {
|
||||
rpc_send_and_release_empty(session, rpc_storage->current_command_id, command_status);
|
||||
rpc_system_storage_reset_state(rpc_storage, session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ App(
|
||||
cdefines=["APP_SPECTRUM_ANALYZER"],
|
||||
requires=["gui"],
|
||||
icon="A_SpectrumAnalyzer_14",
|
||||
stack_size=1 * 1024,
|
||||
stack_size=4 * 1024,
|
||||
order=12,
|
||||
)
|
||||
|
||||
@@ -274,24 +274,26 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) {
|
||||
if(parsed_count == EOF || parsed_count != 1) {
|
||||
storage_cli_print_usage();
|
||||
} else if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
uint8_t* data = malloc(buffer_size);
|
||||
uint64_t file_size = storage_file_size(file);
|
||||
|
||||
printf("Size: %lu\r\n", (uint32_t)file_size);
|
||||
|
||||
while(file_size > 0) {
|
||||
printf("\r\nReady?\r\n");
|
||||
cli_getc(cli);
|
||||
if(buffer_size) {
|
||||
uint8_t* data = malloc(buffer_size);
|
||||
while(file_size > 0) {
|
||||
printf("\r\nReady?\r\n");
|
||||
cli_getc(cli);
|
||||
|
||||
uint16_t read_size = storage_file_read(file, data, buffer_size);
|
||||
for(uint16_t i = 0; i < read_size; i++) {
|
||||
putchar(data[i]);
|
||||
uint16_t read_size = storage_file_read(file, data, buffer_size);
|
||||
for(uint16_t i = 0; i < read_size; i++) {
|
||||
putchar(data[i]);
|
||||
}
|
||||
file_size -= read_size;
|
||||
}
|
||||
file_size -= read_size;
|
||||
free(data);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
free(data);
|
||||
} else {
|
||||
storage_cli_print_error(storage_file_get_error(file));
|
||||
}
|
||||
@@ -315,19 +317,21 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) {
|
||||
if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) {
|
||||
printf("Ready\r\n");
|
||||
|
||||
uint8_t* buffer = malloc(buffer_size);
|
||||
if(buffer_size) {
|
||||
uint8_t* buffer = malloc(buffer_size);
|
||||
|
||||
for(uint32_t i = 0; i < buffer_size; i++) {
|
||||
buffer[i] = cli_getc(cli);
|
||||
for(uint32_t i = 0; i < buffer_size; i++) {
|
||||
buffer[i] = cli_getc(cli);
|
||||
}
|
||||
|
||||
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
||||
|
||||
if(written_size != buffer_size) {
|
||||
storage_cli_print_error(storage_file_get_error(file));
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
||||
|
||||
if(written_size != buffer_size) {
|
||||
storage_cli_print_error(storage_file_get_error(file));
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
} else {
|
||||
storage_cli_print_error(storage_file_get_error(file));
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
@@ -1,5 +1,5 @@
|
||||
V:0
|
||||
T:1659970246
|
||||
T:1660063645
|
||||
D:badusb
|
||||
D:dolphin
|
||||
D:infrared
|
||||
@@ -241,8 +241,8 @@ F:33b8fde22f34ef556b64b77164bc19b0:578:dolphin/L3_Lab_research_128x54/frame_8.bm
|
||||
F:f267f0654781049ca323b11bb4375519:581:dolphin/L3_Lab_research_128x54/frame_9.bm
|
||||
F:41106c0cbc5144f151b2b2d3daaa0527:727:dolphin/L3_Lab_research_128x54/meta.txt
|
||||
D:infrared/assets
|
||||
F:14011ff164000afe6c74a5ca30738813:59323:infrared/assets/ac.ir
|
||||
F:b61d602f6a60555f2d92d4eebfa27924:27419:infrared/assets/audio.ir
|
||||
F:0620df2adc5e12f2a9d9c3ac29826ce3:60950:infrared/assets/ac.ir
|
||||
F:a0ac7ed0629a93b234d1790bf8bfb4c6:26781:infrared/assets/audio.ir
|
||||
F:45d36ceeac6be64eea3a0615a612ccbc:107466:infrared/assets/tv.ir
|
||||
F:a157a80f5a668700403d870c23b9567d:470:music_player/Marble_Machine.fmf
|
||||
D:nfc/assets
|
||||
@@ -252,9 +252,9 @@ F:41b4f08774249014cb8d3dffa5f5c07d:1757:nfc/assets/currency_code.nfc
|
||||
F:12674515290ad9edcabc82f7695350f8:50737:nfc/assets/mf_classic_dict.nfc
|
||||
D:subghz/assets
|
||||
F:dda1ef895b8a25fde57c874feaaef997:650:subghz/assets/came_atomo
|
||||
F:27d732a3362969ac187c8f5ff0afc22a:286:subghz/assets/dangerous_settings
|
||||
F:50cf77ba8b935ee6cb3b6f111cf2d93d:286:subghz/assets/dangerous_settings
|
||||
F:111d2b8df83e27fd889fc5e270297865:3231:subghz/assets/keeloq_mfcodes
|
||||
F:9214f9c10463b746a27e82ce0b96e040:465:subghz/assets/keeloq_mfcodes_user
|
||||
F:bb48d7d7db4f6e849436d0e1a9b7a1a7:633:subghz/assets/keeloq_mfcodes_user_example
|
||||
F:653bd8d349055a41e1152e557d4a52d3:202:subghz/assets/nice_flor_s
|
||||
F:470919d764538023a7f73ebae2853797:2106:subghz/assets/setting_user
|
||||
D:u2f/assets
|
||||
|
||||
@@ -3,6 +3,14 @@ Version: 1
|
||||
#
|
||||
# Universal AC IR codes - Brute force updated by jaroslavmraz and fixed by MX
|
||||
# BETA version
|
||||
#
|
||||
# Old SAMSUNG AC
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 3027 9039 538 1530 514 558 490 557 491 582 486 560 488 559 488 584 464 583 464 582 486 1554 490 583 485 562 486 1554 490 584 484 1556 488 1554 510 562 485 1555 509 1531 533 1535 509 1558 569 1473 591 1475 517 1550 566 1475 517 556 492 581 487 559 488 558 490 557 491 582 486 560 487 559 488 558 489 583 464 582 486 560 508 565 482 1584 460 1556 508 1558 517 1524 572 1495 518 1551 513 1527 517 555 493 581 487 559 488 558 510 562 485 561 486 560 487 1579 485 1557 518 1523 541 1526 466
|
||||
#
|
||||
# Airmet AC by JEREMYNO
|
||||
#
|
||||
@@ -569,3 +577,11 @@ type: parsed
|
||||
protocol: NECext
|
||||
address: 01 08 00 00
|
||||
command: 3F 00 00 00
|
||||
#
|
||||
# Old SAMSUNG AC
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 3027 9036 541 1580 484 588 491 556 492 555 482 564 484 589 459 587 481 565 483 564 484 1583 492 555 482 564 484 589 479 1561 514 1527 517 583 485 1555 489 1552 513 1581 484 1531 513 534 514 585 463 584 484 562 486 561 486 560 488 585 483 589 479 567 512 561 486 560 488 559 489 558 490 583 485 561 487 560 488 558 490 1578 486 1580 484 562 517 1577 487 559 489 558 490 583 485 1555 509 564 484 563 485 1582 483 1532 543 1576 488 559 489 584 464 583 485 587 492 555 482 564 432 1924 2973 9041 536 1531 513 559 489 584 484 563 516 557 491 556 481 591 488 559 489 558 490 1577 487 559 489 558 490 1577 487 1580 484 1530 514 1553 512 562 485 1555 509 1531 513 1555 509 1558 507 1534 510 1557 518 1524 509 1557 518 555 493 555 513 559 488 558 490 583 485 561 486 560 488 559 489 584 484 562 486 561 486 560 487 585 483 1557 487 1554 510 1557 507 1533 511 1557 538 1528 516 1578 455 591 488 559 489 558 489 557 491 582 486 560 487 559 488 584 484 562 517 1524 509 1558 465
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Do you want to damage your flipper CC1101 radio chip by using Frequencies that outside HW specs?
|
||||
# CC1101 Frequency range specs: 300-348 MHz, 386-464 MHz, and 778-928 MHz
|
||||
# CC1101 Frequency range specs: 300-348 MHz, 386-464 MHz, and 778-928 MHz
|
||||
# This setting will extend to: 281-361 MHz, 378-481 MHz, and 749-962 MHz
|
||||
yes_i_want_to_destroy_my_flipper: false
|
||||
yes_i_want_to_destroy_my_flipper: false
|
||||
|
||||
+3
@@ -1,3 +1,6 @@
|
||||
# Rename or Create new file with name keeloq_mfcodes_user and copy contents of that file, remove sample keys and add yours
|
||||
# keep empty line at the end of that file!
|
||||
#
|
||||
# for adding manufacture keys
|
||||
# AABBCCDDEEFFAABB:X:NAME\r\n
|
||||
# AABBCCDDEEFFAABB - man 64 bit
|
||||
@@ -341,13 +341,13 @@ void furi_hal_nfc_listen_start(FuriHalNfcDevData* nfc_data) {
|
||||
if(nfc_data->uid_len == 4) {
|
||||
pt_memory[12] = nfc_data->sak & ~FURI_HAL_NFC_UID_INCOMPLETE;
|
||||
} else {
|
||||
pt_memory[12] = nfc_data->sak | FURI_HAL_NFC_UID_INCOMPLETE;
|
||||
pt_memory[12] = FURI_HAL_NFC_UID_INCOMPLETE;
|
||||
}
|
||||
pt_memory[13] = nfc_data->sak & ~FURI_HAL_NFC_UID_INCOMPLETE;
|
||||
pt_memory[14] = nfc_data->sak & ~FURI_HAL_NFC_UID_INCOMPLETE;
|
||||
|
||||
st25r3916WritePTMem(pt_memory, sizeof(pt_memory));
|
||||
// Go to sence
|
||||
// Go to sense
|
||||
st25r3916ExecuteCommand(ST25R3916_CMD_GOTO_SENSE);
|
||||
}
|
||||
|
||||
@@ -507,6 +507,9 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_
|
||||
uint8_t rxe = 0;
|
||||
uint32_t start = DWT->CYCCNT;
|
||||
while(true) {
|
||||
if(!rfalIsExtFieldOn()) {
|
||||
return false;
|
||||
}
|
||||
if(furi_hal_gpio_read(&gpio_nfc_irq_rfid_pull) == true) {
|
||||
st25r3916ReadRegister(ST25R3916_REG_IRQ_MAIN, &rxe);
|
||||
if(rxe & (1 << 4)) {
|
||||
|
||||
@@ -771,6 +771,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
|
||||
// Read command
|
||||
while(!command_processed) {
|
||||
if(!is_encrypted) {
|
||||
crypto1_reset(&emulator->crypto);
|
||||
memcpy(plain_data, tx_rx->rx_data, tx_rx->rx_bits / 8);
|
||||
} else {
|
||||
if(!furi_hal_nfc_tx_rx(tx_rx, 300)) {
|
||||
@@ -803,7 +804,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
|
||||
access_key = MfClassicKeyB;
|
||||
}
|
||||
|
||||
uint32_t nonce = prng_successor(DWT->CYCCNT, 32);
|
||||
uint32_t nonce = prng_successor(DWT->CYCCNT, 32) ^ 0xAA;
|
||||
uint8_t nt[4];
|
||||
uint8_t nt_keystream[4];
|
||||
nfc_util_num2bytes(nonce, 4, nt);
|
||||
@@ -858,7 +859,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
|
||||
uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0);
|
||||
if(cardRr != prng_successor(nonce, 64)) {
|
||||
FURI_LOG_T(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64));
|
||||
// Don't send NACK, as tag don't send it
|
||||
// Don't send NACK, as the tag doesn't send it
|
||||
command_processed = true;
|
||||
break;
|
||||
}
|
||||
@@ -897,7 +898,18 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
|
||||
} else {
|
||||
if(!mf_classic_is_allowed_access(
|
||||
emulator, block, access_key, MfClassicActionDataRead)) {
|
||||
memset(block_data, 0, 16);
|
||||
// Send NACK
|
||||
uint8_t nack = 0x04;
|
||||
if(is_encrypted) {
|
||||
mf_crypto1_encrypt(
|
||||
&emulator->crypto, NULL, &nack, 4, tx_rx->tx_data, tx_rx->tx_parity);
|
||||
} else {
|
||||
tx_rx->tx_data[0] = nack;
|
||||
}
|
||||
tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
|
||||
tx_rx->tx_bits = 4;
|
||||
furi_hal_nfc_tx_rx(tx_rx, 300);
|
||||
break;
|
||||
}
|
||||
}
|
||||
nfca_append_crc16(block_data, 16);
|
||||
|
||||
@@ -85,6 +85,10 @@ void path_concat(const char* path, const char* suffix, string_t out_path) {
|
||||
}
|
||||
|
||||
bool path_contains_only_ascii(const char* path) {
|
||||
if(!path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* name_pos = strrchr(path, '/');
|
||||
if(name_pos == NULL) {
|
||||
name_pos = path;
|
||||
|
||||
Reference in New Issue
Block a user