mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-07 19:01:54 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL (256)
|
||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_HALF \
|
||||
(SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL / 2)
|
||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_GUARD_TIME 999
|
||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_GUARD_TIME 999 << 1
|
||||
|
||||
/** SubGhz state */
|
||||
typedef enum {
|
||||
@@ -500,7 +500,7 @@ static void subghz_device_cc1101_ext_capture_ISR() {
|
||||
|
||||
subghz_device_cc1101_ext->async_rx.capture_callback(
|
||||
true,
|
||||
LL_TIM_GetCounter(TIM17),
|
||||
LL_TIM_GetCounter(TIM17) << 1,
|
||||
(void*)subghz_device_cc1101_ext->async_rx.capture_callback_context);
|
||||
}
|
||||
} else {
|
||||
@@ -510,11 +510,11 @@ static void subghz_device_cc1101_ext_capture_ISR() {
|
||||
|
||||
subghz_device_cc1101_ext->async_rx.capture_callback(
|
||||
false,
|
||||
LL_TIM_GetCounter(TIM17),
|
||||
LL_TIM_GetCounter(TIM17) << 1,
|
||||
(void*)subghz_device_cc1101_ext->async_rx.capture_callback_context);
|
||||
}
|
||||
}
|
||||
LL_TIM_SetCounter(TIM17, 6);
|
||||
LL_TIM_SetCounter(TIM17, 4); //8>>1
|
||||
}
|
||||
|
||||
void subghz_device_cc1101_ext_start_async_rx(
|
||||
@@ -529,7 +529,8 @@ void subghz_device_cc1101_ext_start_async_rx(
|
||||
furi_hal_bus_enable(FuriHalBusTIM17);
|
||||
|
||||
// Configure TIM
|
||||
LL_TIM_SetPrescaler(TIM17, 64 - 1);
|
||||
//Set the timer resolution to 2 µs
|
||||
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
|
||||
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
||||
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
||||
@@ -623,7 +624,7 @@ static void subghz_device_cc1101_ext_async_tx_refill(uint32_t* buffer, size_t sa
|
||||
|
||||
uint32_t duration = level_duration_get_duration(ld);
|
||||
furi_assert(duration > 0);
|
||||
*buffer = duration - 1;
|
||||
*buffer = duration >> 1;
|
||||
buffer++;
|
||||
samples--;
|
||||
}
|
||||
@@ -709,7 +710,8 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
|
||||
furi_hal_bus_enable(FuriHalBusTIM17);
|
||||
|
||||
// Configure TIM
|
||||
LL_TIM_SetPrescaler(TIM17, 64 - 1);
|
||||
// Set the timer resolution to 2 µs
|
||||
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
|
||||
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
||||
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
dist/*
|
||||
.vscode
|
||||
.clang-format
|
||||
.editorconfig
|
||||
+4
@@ -11,4 +11,8 @@ App(
|
||||
order=75,
|
||||
fap_icon="doom_10px.png",
|
||||
fap_category="Games",
|
||||
fap_icon_assets="assets",
|
||||
fap_author="@xMasterX & @Svarich & @hedger (original code by @p4nic4ttack)",
|
||||
fap_version="1.0",
|
||||
fap_description="Will it run Doom?",
|
||||
)
|
||||
|
||||
+1
-75
@@ -1,78 +1,4 @@
|
||||
#include "assets_icons.h"
|
||||
|
||||
#include <gui/icon_i.h>
|
||||
|
||||
// Inverted icons
|
||||
|
||||
const uint8_t _I_fire_inv_0[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x40, 0xee, 0x00, 0x80, 0xe6, 0x00,
|
||||
0x80, 0xa7, 0x01, 0x80, 0xc7, 0x03, 0x40, 0x45, 0x03, 0xe0, 0x41, 0x07, 0xf8, 0x82, 0x9f, 0xb9,
|
||||
0x01, 0x3e, 0x7c, 0x00, 0x7a, 0x6e, 0x00, 0x56, 0x1c, 0x00, 0x6c, 0xf4, 0x01, 0x3a, 0x6c, 0x00,
|
||||
0x7e, 0xfc, 0x00, 0x1a, 0x08, 0x00, 0x3c, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
const uint8_t* const _I_fire_inv[] = {_I_fire_inv_0};
|
||||
|
||||
const uint8_t _I_gun_inv_0[] = {
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x80, 0x23, 0x00, 0x00, 0x40,
|
||||
0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x57, 0x00, 0x00, 0x20, 0x8b, 0x00, 0x00,
|
||||
0x90, 0x11, 0x01, 0x00, 0x98, 0x00, 0x00, 0x00, 0xb0, 0x43, 0x01, 0x00, 0x94, 0x81, 0x03,
|
||||
0x00, 0xd0, 0x45, 0x04, 0x00, 0x8c, 0x02, 0x02, 0x00, 0xc4, 0x00, 0x03, 0x00, 0xc8, 0x00,
|
||||
0x02, 0x00, 0x4e, 0x40, 0x00, 0x00, 0x92, 0x00, 0x02, 0x80, 0x07, 0x15, 0x04, 0xe0, 0x8f,
|
||||
0x00, 0x0c, 0xd0, 0x9d, 0x07, 0x17, 0xe0, 0x3a, 0xc0, 0x3f, 0xe0, 0xf7, 0xff, 0x77, 0xe0,
|
||||
0xae, 0xfe, 0x4b, 0xd8, 0xdd, 0xff, 0x4d, 0x88, 0xea, 0xbe, 0x26, 0x4c, 0xf5, 0xff, 0x17,
|
||||
0xc8, 0xfa, 0xae, 0x0b, 0xcc, 0xff, 0xdf, 0x19, 0xe8, 0xeb, 0xa7, 0x00, 0xd8, 0xf1, 0x4d,
|
||||
0x0c, 0xc0, 0xbe, 0x1a, 0x08, 0xf6, 0xfd, 0x37, 0x04,
|
||||
};
|
||||
const uint8_t* const _I_gun_inv[] = {_I_gun_inv_0};
|
||||
|
||||
const uint8_t _I_gun_mask_inv_0[] = {
|
||||
0x01, 0x00, 0x53, 0x00, 0x00, 0x0c, 0x38, 0x04, 0x38, 0x09, 0xf8, 0x0c, 0x78, 0x17, 0xf0,
|
||||
0x18, 0xf8, 0x00, 0x67, 0xff, 0x01, 0xaf, 0xc3, 0xff, 0x01, 0x80, 0x7e, 0x3f, 0xf0, 0x38,
|
||||
0x07, 0xf0, 0x0e, 0x40, 0x31, 0x03, 0x8f, 0xfb, 0xff, 0x07, 0x01, 0x94, 0x3c, 0x0e, 0xc0,
|
||||
0x35, 0xff, 0x85, 0xc8, 0x06, 0x30, 0x7e, 0x00, 0x0c, 0x61, 0xe2, 0xe1, 0xff, 0xc7, 0xc5,
|
||||
0xc3, 0xff, 0x9f, 0x80, 0xca, 0xfe, 0x03, 0x2f, 0xf8, 0x0c, 0xc6, 0xc2, 0x03, 0x4b, 0xf8,
|
||||
0xa8, 0x42, 0xe2, 0x03, 0x28, 0xf8, 0x1e, 0x80, 0x68, 0x1e, 0x28, 0x78,
|
||||
};
|
||||
const uint8_t* const _I_gun_mask_inv[] = {_I_gun_mask_inv_0};
|
||||
|
||||
const uint8_t _I_logo_inv_0[] = {
|
||||
0x01, 0x00, 0x92, 0x01, 0x00, 0x78, 0x03, 0xc0, 0x03, 0xfc, 0xff, 0xff, 0xfc, 0x1f, 0xf9, 0xff,
|
||||
0xe3, 0xff, 0x0f, 0x8f, 0xfc, 0x2f, 0xe0, 0xf3, 0xdc, 0x6e, 0xf7, 0x7b, 0x1d, 0xdd, 0xef, 0x79,
|
||||
0xbb, 0xcd, 0xce, 0xf7, 0x13, 0xb0, 0x79, 0xfc, 0x03, 0xe3, 0xfb, 0x01, 0x0f, 0xfb, 0xff, 0xbf,
|
||||
0x11, 0x8c, 0x7c, 0x1e, 0x7e, 0x0f, 0x77, 0xbb, 0xd4, 0x02, 0x10, 0x00, 0xeb, 0xad, 0xde, 0xc8,
|
||||
0x70, 0x3c, 0xf8, 0x01, 0xf7, 0xbf, 0xff, 0x20, 0xe0, 0xf3, 0xc0, 0x6e, 0x80, 0x0d, 0x7a, 0xde,
|
||||
0x40, 0x83, 0xf8, 0x03, 0x10, 0xfa, 0x70, 0x07, 0xee, 0x02, 0x18, 0x30, 0x3d, 0x0a, 0xe3, 0xfb,
|
||||
0x83, 0x86, 0xc7, 0x82, 0x1f, 0x1f, 0xf8, 0xfd, 0x61, 0x5a, 0x0d, 0x54, 0x0b, 0x55, 0xaa, 0xc0,
|
||||
0x00, 0x84, 0x0c, 0x21, 0xf4, 0x8f, 0xf4, 0x3b, 0x70, 0x3e, 0xf7, 0x7b, 0x01, 0x9f, 0xef, 0xf7,
|
||||
0xc3, 0xfe, 0x1f, 0x6f, 0x87, 0xee, 0x07, 0xfe, 0xff, 0x60, 0x07, 0xfe, 0x1f, 0x88, 0xef, 0xc3,
|
||||
0xf3, 0x01, 0xfe, 0x7f, 0x30, 0x1b, 0xdf, 0xef, 0xf6, 0x0a, 0x1f, 0xf0, 0x79, 0xd0, 0x22, 0xf7,
|
||||
0x0b, 0x9c, 0x0e, 0xed, 0x76, 0x80, 0x4d, 0xee, 0xf7, 0x71, 0xff, 0x87, 0xd6, 0x2b, 0x50, 0xa8,
|
||||
0xc0, 0x6a, 0x95, 0x48, 0x04, 0x56, 0xab, 0x55, 0x1f, 0xf8, 0xff, 0xc7, 0xfe, 0x3f, 0xaa, 0xe4,
|
||||
0x02, 0x3b, 0x55, 0xae, 0x8f, 0xfc, 0xbf, 0xe1, 0xff, 0x0f, 0xf8, 0x7d, 0x61, 0x18, 0x0c, 0x44,
|
||||
0x03, 0x11, 0x88, 0x02, 0x0e, 0x23, 0x04, 0x0e, 0x30, 0xfa, 0x41, 0x43, 0xe2, 0x06, 0x18, 0xa8,
|
||||
0x18, 0x43, 0xe9, 0x02, 0xd0, 0x68, 0xa1, 0x5a, 0x2d, 0x51, 0x10, 0x70, 0x5a, 0x21, 0xfc, 0x45,
|
||||
0x43, 0xe3, 0x50, 0x0f, 0xc4, 0x20, 0x72, 0x20, 0x22, 0x02, 0x16, 0x00, 0x7e, 0xd5, 0x4a, 0x8d,
|
||||
0x54, 0x3e, 0x35, 0x40, 0xfb, 0x80, 0x3c, 0x3e, 0x35, 0x5a, 0x09, 0xe8, 0x6a, 0x87, 0xc1, 0x23,
|
||||
0x88, 0xfd, 0x40, 0x0c, 0x09, 0x20, 0xfa, 0x87, 0x06, 0x00, 0x1f, 0x38, 0x0c, 0x50, 0x3e, 0xa0,
|
||||
0x0f, 0x0f, 0x8c, 0x56, 0x00, 0x5c, 0x1a, 0x80, 0x90, 0x62, 0x03, 0xf6, 0x80, 0x42, 0x17, 0xc2,
|
||||
0x7b, 0x10, 0x20, 0x87, 0xde, 0xa9, 0x04, 0x80, 0x54, 0x20, 0x94, 0x08, 0xa0, 0x24, 0x47, 0xf5,
|
||||
0x01, 0x20, 0x54, 0x44, 0x18, 0x80, 0x42, 0x88, 0x17, 0xfc, 0x7e, 0xb4, 0x40, 0x4c, 0x12, 0x04,
|
||||
0x01, 0xe3, 0xf4, 0x2a, 0xf8, 0x03, 0xc0, 0x1f, 0xe0, 0xbc, 0xcf, 0xb8, 0xf8, 0x1e, 0xbf, 0xcc,
|
||||
0x5b, 0x12, 0x0c, 0x56, 0x0a, 0x51, 0x82, 0xa8, 0x28, 0x08, 0x1f, 0x32, 0x0c, 0x00, 0x3e, 0x85,
|
||||
0xe3, 0x1e, 0x17, 0x8f, 0x4f, 0xe6, 0x1f, 0x99, 0x44, 0x0a, 0x10, 0x2f, 0x13, 0xb4, 0xc8, 0x29,
|
||||
0x03, 0xf3, 0x89, 0x03, 0xe7, 0x10, 0x5f, 0x2a, 0x87, 0xd1, 0x1b, 0xe0, 0x0f, 0x00, 0x78, 0x03,
|
||||
0xc0, 0x1e, 0x00, 0xf0, 0x02, 0x00,
|
||||
};
|
||||
const uint8_t* const _I_logo_inv[] = {_I_logo_inv_0};
|
||||
|
||||
const Icon I_fire_inv =
|
||||
{.width = 24, .height = 20, .frame_count = 1, .frame_rate = 0, .frames = _I_fire_inv};
|
||||
const Icon I_gun_inv =
|
||||
{.width = 32, .height = 32, .frame_count = 1, .frame_rate = 0, .frames = _I_gun_inv};
|
||||
const Icon I_gun_mask_inv =
|
||||
{.width = 32, .height = 32, .frame_count = 1, .frame_rate = 0, .frames = _I_gun_mask_inv};
|
||||
const Icon I_logo_inv =
|
||||
{.width = 128, .height = 64, .frame_count = 1, .frame_rate = 0, .frames = _I_logo_inv};
|
||||
#include "assets.h"
|
||||
|
||||
const uint8_t space[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const uint8_t zero[] = {0x00, 0x60, 0x90, 0x90, 0x90, 0x60};
|
||||
-6
@@ -41,12 +41,6 @@
|
||||
#define GRADIENT_WHITE 7
|
||||
#define GRADIENT_BLACK 0
|
||||
|
||||
// Inverted icons
|
||||
extern const Icon I_fire_inv;
|
||||
extern const Icon I_gun_inv;
|
||||
extern const Icon I_gun_mask_inv;
|
||||
extern const Icon I_logo_inv;
|
||||
|
||||
// Fonts
|
||||
extern const uint8_t zero[];
|
||||
extern const uint8_t one[];
|
||||
Vendored
+12
-14
@@ -1,9 +1,8 @@
|
||||
#include <gui/gui.h>
|
||||
#include <gui/canvas_i.h>
|
||||
#include <furi_hal.h>
|
||||
#include <u8g2_glue.h>
|
||||
#include "constants.h"
|
||||
#include "compiled/assets_icons.h"
|
||||
#include <doom_icons.h>
|
||||
#include "assets.h"
|
||||
|
||||
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
|
||||
|
||||
@@ -50,14 +49,12 @@ void fadeScreen(uint8_t intensity, bool color, Canvas* const canvas);
|
||||
bool getGradientPixel(uint8_t x, uint8_t y, uint8_t i);
|
||||
double getActualFps();
|
||||
void fps();
|
||||
void setupDisplay(Canvas* canvas);
|
||||
uint8_t reverse_bits(uint8_t num);
|
||||
|
||||
// FPS control
|
||||
double delta = 1;
|
||||
uint32_t lastFrameTime = 0;
|
||||
uint8_t zbuffer[128]; /// 128 = screen width & REMOVE WHEN DISPLAY.H IMPLEMENTED
|
||||
uint8_t* display_buf = NULL;
|
||||
|
||||
void drawGun(
|
||||
int16_t x,
|
||||
@@ -88,12 +85,6 @@ void drawVLine(uint8_t x, int8_t start_y, int8_t end_y, uint8_t intensity, Canva
|
||||
}
|
||||
}
|
||||
|
||||
void setupDisplay(Canvas* canvas) {
|
||||
memset(zbuffer, 0xff, 128);
|
||||
display_buf = (uint8_t*)canvas->fb.tile_buf_ptr;
|
||||
//display_buf = u8g2_GetBufferPtr(&canvas->fb);
|
||||
}
|
||||
|
||||
void drawBitmap(
|
||||
int16_t x,
|
||||
int16_t y,
|
||||
@@ -102,13 +93,20 @@ void drawBitmap(
|
||||
int16_t h,
|
||||
uint16_t color,
|
||||
Canvas* const canvas) {
|
||||
UNUSED(color);
|
||||
canvas_draw_icon_bitmap(canvas, x, y, w, h, i);
|
||||
UNUSED(w);
|
||||
UNUSED(h);
|
||||
if(!color) {
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
canvas_draw_icon(canvas, x, y, i);
|
||||
if(!color) {
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
void drawText(uint8_t x, uint8_t y, uint8_t num, Canvas* const canvas) {
|
||||
char buf[4];
|
||||
itoa(num, buf, 10);
|
||||
snprintf(buf, 4, "%d", num);
|
||||
drawTextSpace(x, y, buf, 1, canvas);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+5
-7
@@ -6,7 +6,7 @@
|
||||
#include <sys/time.h>
|
||||
#include "sound.h"
|
||||
#include "display.h"
|
||||
#include "compiled/assets_icons.h"
|
||||
#include "assets.h"
|
||||
#include "constants.h"
|
||||
#include "entities.h"
|
||||
#include "types.h"
|
||||
@@ -228,12 +228,12 @@ UID detectCollision(
|
||||
bool only_walls,
|
||||
PluginState* const plugin_state) {
|
||||
// Wall collision
|
||||
uint8_t round_x = (int)pos->x + (int)relative_x;
|
||||
uint8_t round_y = (int)pos->y + (int)relative_y;
|
||||
uint8_t round_x = (int)(pos->x + relative_x);
|
||||
uint8_t round_y = (int)(pos->y + relative_y);
|
||||
uint8_t block = getBlockAt(level, round_x, round_y);
|
||||
|
||||
if(block == E_WALL) {
|
||||
//playSound(hit_wall_snd, HIT_WALL_SND_LEN);
|
||||
// playSound(hit_wall_snd, HIT_WALL_SND_LEN);
|
||||
return create_uid(block, round_x, round_y);
|
||||
}
|
||||
|
||||
@@ -774,7 +774,6 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
PluginState* plugin_state = ctx;
|
||||
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
|
||||
if(plugin_state->init) setupDisplay(canvas);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
|
||||
@@ -860,7 +859,6 @@ static void doom_game_update_timer_callback(FuriMessageQueue* event_queue) {
|
||||
static void doom_game_tick(PluginState* const plugin_state) {
|
||||
if(plugin_state->scene == GAME_PLAY) {
|
||||
//fps();
|
||||
memset(display_buf, 0, SCREEN_WIDTH * (RENDER_HEIGHT / 8));
|
||||
//player is alive
|
||||
if(plugin_state->player.health > 0) {
|
||||
if(plugin_state->up) {
|
||||
@@ -988,7 +986,7 @@ int32_t doom_app() {
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
//////////////////////////////////
|
||||
if(display_buf != NULL) plugin_state->init = false;
|
||||
plugin_state->init = false;
|
||||
|
||||
PluginEvent event;
|
||||
#ifdef SOUND
|
||||
|
||||
+129
-127
@@ -73,143 +73,145 @@ int32_t i2ctools_app(void* p) {
|
||||
// Share scanner with sender
|
||||
i2ctools->sender->scanner = i2ctools->scanner;
|
||||
|
||||
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
// Back
|
||||
if(event.key == InputKeyBack && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
break;
|
||||
} else {
|
||||
if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
stop_interrupts();
|
||||
i2ctools->sniffer->started = false;
|
||||
i2ctools->sniffer->state = I2C_BUS_FREE;
|
||||
}
|
||||
i2ctools->main_view->current_view = MAIN_VIEW;
|
||||
}
|
||||
}
|
||||
// Up
|
||||
else if(event.key == InputKeyUp && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
if((i2ctools->main_view->menu_index > SCAN_VIEW)) {
|
||||
i2ctools->main_view->menu_index--;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
if(i2ctools->scanner->menu_index > 0) {
|
||||
i2ctools->scanner->menu_index--;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->row_index > 0) {
|
||||
i2ctools->sniffer->row_index--;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value < 0xFF) {
|
||||
i2ctools->sender->value++;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Long Up
|
||||
else if(
|
||||
event.key == InputKeyUp &&
|
||||
(event.type == InputTypeLong || event.type == InputTypeRepeat)) {
|
||||
if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
if(i2ctools->scanner->menu_index > 5) {
|
||||
i2ctools->scanner->menu_index -= 5;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value < 0xF9) {
|
||||
i2ctools->sender->value += 5;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->row_index > 5) {
|
||||
i2ctools->sniffer->row_index -= 5;
|
||||
while(1) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
// Back
|
||||
if(event.key == InputKeyBack && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
break;
|
||||
} else {
|
||||
i2ctools->sniffer->row_index = 0;
|
||||
if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
stop_interrupts();
|
||||
i2ctools->sniffer->started = false;
|
||||
i2ctools->sniffer->state = I2C_BUS_FREE;
|
||||
}
|
||||
i2ctools->main_view->current_view = MAIN_VIEW;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Down
|
||||
else if(event.key == InputKeyDown && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
if(i2ctools->main_view->menu_index < MENU_SIZE - 1) {
|
||||
i2ctools->main_view->menu_index++;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
if(i2ctools->scanner->menu_index < ((int)i2ctools->scanner->nb_found / 3)) {
|
||||
i2ctools->scanner->menu_index++;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if((i2ctools->sniffer->row_index + 3) <
|
||||
(int)i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data_index) {
|
||||
i2ctools->sniffer->row_index++;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value > 0x00) {
|
||||
i2ctools->sender->value--;
|
||||
i2ctools->sender->sended = false;
|
||||
// Up
|
||||
else if(event.key == InputKeyUp && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
if((i2ctools->main_view->menu_index > SCAN_VIEW)) {
|
||||
i2ctools->main_view->menu_index--;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
if(i2ctools->scanner->menu_index > 0) {
|
||||
i2ctools->scanner->menu_index--;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->row_index > 0) {
|
||||
i2ctools->sniffer->row_index--;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value < 0xFF) {
|
||||
i2ctools->sender->value++;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Long Down
|
||||
else if(
|
||||
event.key == InputKeyDown &&
|
||||
(event.type == InputTypeLong || event.type == InputTypeRepeat)) {
|
||||
if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value > 0x05) {
|
||||
i2ctools->sender->value -= 5;
|
||||
i2ctools->sender->sended = false;
|
||||
} else {
|
||||
i2ctools->sender->value = 0;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if((i2ctools->sniffer->row_index + 8) <
|
||||
(int)i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data_index) {
|
||||
i2ctools->sniffer->row_index += 5;
|
||||
// Long Up
|
||||
else if(
|
||||
event.key == InputKeyUp &&
|
||||
(event.type == InputTypeLong || event.type == InputTypeRepeat)) {
|
||||
if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
if(i2ctools->scanner->menu_index > 5) {
|
||||
i2ctools->scanner->menu_index -= 5;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value < 0xF9) {
|
||||
i2ctools->sender->value += 5;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->row_index > 5) {
|
||||
i2ctools->sniffer->row_index -= 5;
|
||||
} else {
|
||||
i2ctools->sniffer->row_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Down
|
||||
else if(event.key == InputKeyDown && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
if(i2ctools->main_view->menu_index < MENU_SIZE - 1) {
|
||||
i2ctools->main_view->menu_index++;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
if(i2ctools->scanner->menu_index < ((int)i2ctools->scanner->nb_found / 3)) {
|
||||
i2ctools->scanner->menu_index++;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if((i2ctools->sniffer->row_index + 3) <
|
||||
(int)i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data_index) {
|
||||
i2ctools->sniffer->row_index++;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value > 0x00) {
|
||||
i2ctools->sender->value--;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Long Down
|
||||
else if(
|
||||
event.key == InputKeyDown &&
|
||||
(event.type == InputTypeLong || event.type == InputTypeRepeat)) {
|
||||
if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->value > 0x05) {
|
||||
i2ctools->sender->value -= 5;
|
||||
i2ctools->sender->sended = false;
|
||||
} else {
|
||||
i2ctools->sender->value = 0;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if((i2ctools->sniffer->row_index + 8) <
|
||||
(int)i2ctools->sniffer->frames[i2ctools->sniffer->menu_index].data_index) {
|
||||
i2ctools->sniffer->row_index += 5;
|
||||
}
|
||||
}
|
||||
|
||||
} else if(event.key == InputKeyOk && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
i2ctools->main_view->current_view = i2ctools->main_view->menu_index;
|
||||
} else if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
scan_i2c_bus(i2ctools->scanner);
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
i2ctools->sender->must_send = true;
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->started) {
|
||||
stop_interrupts();
|
||||
i2ctools->sniffer->started = false;
|
||||
i2ctools->sniffer->state = I2C_BUS_FREE;
|
||||
} else {
|
||||
start_interrupts(i2ctools->sniffer);
|
||||
i2ctools->sniffer->started = true;
|
||||
i2ctools->sniffer->state = I2C_BUS_FREE;
|
||||
} else if(event.key == InputKeyOk && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == MAIN_VIEW) {
|
||||
i2ctools->main_view->current_view = i2ctools->main_view->menu_index;
|
||||
} else if(i2ctools->main_view->current_view == SCAN_VIEW) {
|
||||
scan_i2c_bus(i2ctools->scanner);
|
||||
} else if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
i2ctools->sender->must_send = true;
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->started) {
|
||||
stop_interrupts();
|
||||
i2ctools->sniffer->started = false;
|
||||
i2ctools->sniffer->state = I2C_BUS_FREE;
|
||||
} else {
|
||||
start_interrupts(i2ctools->sniffer);
|
||||
i2ctools->sniffer->started = true;
|
||||
i2ctools->sniffer->state = I2C_BUS_FREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(event.key == InputKeyRight && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->address_idx < (i2ctools->scanner->nb_found - 1)) {
|
||||
i2ctools->sender->address_idx++;
|
||||
i2ctools->sender->sended = false;
|
||||
} else if(event.key == InputKeyRight && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->address_idx < (i2ctools->scanner->nb_found - 1)) {
|
||||
i2ctools->sender->address_idx++;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->menu_index < i2ctools->sniffer->frame_index) {
|
||||
i2ctools->sniffer->menu_index++;
|
||||
i2ctools->sniffer->row_index = 0;
|
||||
}
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->menu_index < i2ctools->sniffer->frame_index) {
|
||||
i2ctools->sniffer->menu_index++;
|
||||
i2ctools->sniffer->row_index = 0;
|
||||
}
|
||||
}
|
||||
} else if(event.key == InputKeyLeft && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->address_idx > 0) {
|
||||
i2ctools->sender->address_idx--;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->menu_index > 0) {
|
||||
i2ctools->sniffer->menu_index--;
|
||||
i2ctools->sniffer->row_index = 0;
|
||||
} else if(event.key == InputKeyLeft && event.type == InputTypeRelease) {
|
||||
if(i2ctools->main_view->current_view == SEND_VIEW) {
|
||||
if(i2ctools->sender->address_idx > 0) {
|
||||
i2ctools->sender->address_idx--;
|
||||
i2ctools->sender->sended = false;
|
||||
}
|
||||
} else if(i2ctools->main_view->current_view == SNIFF_VIEW) {
|
||||
if(i2ctools->sniffer->menu_index > 0) {
|
||||
i2ctools->sniffer->menu_index--;
|
||||
i2ctools->sniffer->row_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+51
-46
@@ -229,53 +229,58 @@ int32_t hex_viewer_app(void* p) {
|
||||
hex_viewer_read_file(hex_viewer);
|
||||
|
||||
InputEvent input;
|
||||
while(furi_message_queue_get(hex_viewer->input_queue, &input, FuriWaitForever) ==
|
||||
FuriStatusOk) {
|
||||
if(input.key == InputKeyBack) {
|
||||
break;
|
||||
} else if(input.key == InputKeyUp) {
|
||||
furi_check(furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(hex_viewer->model->file_offset > 0) {
|
||||
hex_viewer->model->file_offset -= HEX_VIEWER_BYTES_PER_LINE;
|
||||
if(!hex_viewer_read_file(hex_viewer)) break;
|
||||
while(1) {
|
||||
if(furi_message_queue_get(hex_viewer->input_queue, &input, 100) == FuriStatusOk) {
|
||||
if(input.key == InputKeyBack) {
|
||||
break;
|
||||
} else if(input.key == InputKeyUp) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(hex_viewer->model->file_offset > 0) {
|
||||
hex_viewer->model->file_offset -= HEX_VIEWER_BYTES_PER_LINE;
|
||||
if(!hex_viewer_read_file(hex_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyDown) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
uint32_t last_byte_on_screen =
|
||||
hex_viewer->model->file_offset + hex_viewer->model->file_read_bytes;
|
||||
|
||||
if(hex_viewer->model->file_size > last_byte_on_screen) {
|
||||
hex_viewer->model->file_offset += HEX_VIEWER_BYTES_PER_LINE;
|
||||
if(!hex_viewer_read_file(hex_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyLeft) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
hex_viewer->model->mode = !hex_viewer->model->mode;
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyRight) {
|
||||
FuriString* buffer;
|
||||
buffer = furi_string_alloc();
|
||||
furi_string_printf(
|
||||
buffer,
|
||||
"File path: %s\nFile size: %lu (0x%lX)",
|
||||
furi_string_get_cstr(file_path),
|
||||
hex_viewer->model->file_size,
|
||||
hex_viewer->model->file_size);
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(
|
||||
message, "Hex Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_icon(message, &I_hex_10px, 3, 2);
|
||||
dialog_message_set_text(
|
||||
message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop);
|
||||
dialog_message_set_buttons(message, NULL, NULL, "Back");
|
||||
dialog_message_show(dialogs, message);
|
||||
|
||||
furi_string_free(buffer);
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyDown) {
|
||||
furi_check(furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
uint32_t last_byte_on_screen =
|
||||
hex_viewer->model->file_offset + hex_viewer->model->file_read_bytes;
|
||||
|
||||
if(hex_viewer->model->file_size > last_byte_on_screen) {
|
||||
hex_viewer->model->file_offset += HEX_VIEWER_BYTES_PER_LINE;
|
||||
if(!hex_viewer_read_file(hex_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyLeft) {
|
||||
furi_check(furi_mutex_acquire(hex_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
hex_viewer->model->mode = !hex_viewer->model->mode;
|
||||
furi_mutex_release(hex_viewer->mutex);
|
||||
} else if(input.key == InputKeyRight) {
|
||||
FuriString* buffer;
|
||||
buffer = furi_string_alloc();
|
||||
furi_string_printf(
|
||||
buffer,
|
||||
"File path: %s\nFile size: %lu (0x%lX)",
|
||||
furi_string_get_cstr(file_path),
|
||||
hex_viewer->model->file_size,
|
||||
hex_viewer->model->file_size);
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(message, "Hex Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_icon(message, &I_hex_10px, 3, 2);
|
||||
dialog_message_set_text(
|
||||
message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop);
|
||||
dialog_message_set_buttons(message, NULL, NULL, "Back");
|
||||
dialog_message_show(dialogs, message);
|
||||
|
||||
furi_string_free(buffer);
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
|
||||
view_port_update(hex_viewer->view_port);
|
||||
|
||||
+22
-21
@@ -140,30 +140,31 @@ int32_t ir_scope_app(void* p) {
|
||||
|
||||
InputEvent event;
|
||||
bool processing = true;
|
||||
while(processing &&
|
||||
furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||
if(event.type == InputTypeRelease) {
|
||||
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||
while(processing) {
|
||||
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
|
||||
if(event.type == InputTypeRelease) {
|
||||
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||
|
||||
if(event.key == InputKeyBack) {
|
||||
processing = false;
|
||||
} else if(event.key == InputKeyUp) {
|
||||
state.us_per_sample = MIN(1000, state.us_per_sample + 25);
|
||||
state.autoscale = false;
|
||||
} else if(event.key == InputKeyDown) {
|
||||
state.us_per_sample = MAX(25, state.us_per_sample - 25);
|
||||
state.autoscale = false;
|
||||
} else if(event.key == InputKeyOk) {
|
||||
state.autoscale = !state.autoscale;
|
||||
if(state.autoscale)
|
||||
state_set_autoscale(&state);
|
||||
else
|
||||
state.us_per_sample = 200;
|
||||
if(event.key == InputKeyBack) {
|
||||
processing = false;
|
||||
} else if(event.key == InputKeyUp) {
|
||||
state.us_per_sample = MIN(1000, state.us_per_sample + 25);
|
||||
state.autoscale = false;
|
||||
} else if(event.key == InputKeyDown) {
|
||||
state.us_per_sample = MAX(25, state.us_per_sample - 25);
|
||||
state.autoscale = false;
|
||||
} else if(event.key == InputKeyOk) {
|
||||
state.autoscale = !state.autoscale;
|
||||
if(state.autoscale)
|
||||
state_set_autoscale(&state);
|
||||
else
|
||||
state.us_per_sample = 200;
|
||||
}
|
||||
|
||||
furi_mutex_release(state.mutex);
|
||||
}
|
||||
|
||||
view_port_update(view_port);
|
||||
furi_mutex_release(state.mutex);
|
||||
}
|
||||
view_port_update(view_port);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
|
||||
+2
-2
@@ -6,9 +6,9 @@ App(
|
||||
requires=[
|
||||
"gui",
|
||||
],
|
||||
stack_size=1 * 1024,
|
||||
stack_size= 4 * 1024,
|
||||
order=90,
|
||||
fap_version=(1, 1),
|
||||
fap_version=(1, 2),
|
||||
fap_icon="lightmeter.png",
|
||||
fap_category="GPIO",
|
||||
fap_private_libs=[
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
## Lightmeter app for photography
|
||||
|
||||
An application that suggests settings for your manual camera based on the reading of the ambient light sensor. Can also be used in a pure lux meter mode.
|
||||
|
||||
## Supported sensors
|
||||
|
||||
- BH1750
|
||||
- MAX44009
|
||||
|
||||
## Wiring
|
||||
|
||||
| Sensor | Flipper Zero |
|
||||
| ------ | ------------ |
|
||||
| VCC | 3.3V |
|
||||
| GND | GND |
|
||||
| SCL | C0 |
|
||||
| SDA | C1 |
|
||||
@@ -0,0 +1,15 @@
|
||||
## v1.2
|
||||
|
||||
* Lux only screen now has statistics
|
||||
* Settings are now stored on SD card
|
||||
* You can choose the resolution (BH1750 only) and address for sensor
|
||||
|
||||
(thanks to @danielskowronski for contributing to this update)
|
||||
|
||||
## v1.1
|
||||
|
||||
Added support for MAX44009 sensor (thanks to @wosk)
|
||||
|
||||
## v1.0
|
||||
|
||||
Initial release for Flipper Application Catalog
|
||||
@@ -56,6 +56,22 @@ static const char* sensor_type[] = {
|
||||
[SENSOR_MAX44009] = "MAX44009",
|
||||
};
|
||||
|
||||
static const char* measurement_resolution[] = {
|
||||
[LOW_RES] = "Low",
|
||||
[HIGH_RES] = "High",
|
||||
[HIGH_RES2] = "High2",
|
||||
};
|
||||
|
||||
static const char* device_addr_bh1750[] = {
|
||||
[ADDR_LOW] = "0x23",
|
||||
[ADDR_HIGH] = "0x5C",
|
||||
};
|
||||
|
||||
static const char* device_addr_max44009[] = {
|
||||
[ADDR_LOW] = "0x4A",
|
||||
[ADDR_HIGH] = "0x4B",
|
||||
};
|
||||
|
||||
enum LightMeterSubmenuIndex {
|
||||
LightMeterSubmenuIndexISO,
|
||||
LightMeterSubmenuIndexND,
|
||||
@@ -63,6 +79,8 @@ enum LightMeterSubmenuIndex {
|
||||
LightMeterSubmenuIndexBacklight,
|
||||
LightMeterSubmenuIndexLuxMeter,
|
||||
LightMeterSubmenuIndexSensorType,
|
||||
LightMeterSubmenuIndexMeasurementResolution,
|
||||
LightMeterSubmenuIndexI2CAddress,
|
||||
LightMeterSubmenuIndexHelp,
|
||||
LightMeterSubmenuIndexAbout,
|
||||
};
|
||||
@@ -133,6 +151,60 @@ static void lux_only_cb(VariableItem* item) {
|
||||
lightmeter_app_set_config(app, config);
|
||||
}
|
||||
|
||||
static void measurement_resolution_cb(VariableItem* item) {
|
||||
LightMeterApp* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
variable_item_set_current_value_text(item, measurement_resolution[index]);
|
||||
|
||||
LightMeterConfig* config = app->config;
|
||||
config->measurement_resolution = index;
|
||||
lightmeter_app_set_config(app, config);
|
||||
|
||||
lightmeter_app_i2c_init_sensor(app);
|
||||
}
|
||||
|
||||
static void update_item_addr(LightMeterApp* app) {
|
||||
VariableItem* item = app->var_item_addr;
|
||||
switch(app->config->sensor_type) {
|
||||
case SENSOR_BH1750:
|
||||
variable_item_set_current_value_index(item, app->config->device_addr);
|
||||
variable_item_set_current_value_text(item, device_addr_bh1750[app->config->device_addr]);
|
||||
break;
|
||||
case SENSOR_MAX44009:
|
||||
variable_item_set_current_value_index(item, app->config->device_addr);
|
||||
variable_item_set_current_value_text(item, device_addr_max44009[app->config->device_addr]);
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %ld", app->config->sensor_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void device_addr_cb(VariableItem* item) {
|
||||
LightMeterApp* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
switch(app->config->sensor_type) {
|
||||
case SENSOR_BH1750:
|
||||
variable_item_set_current_value_text(item, device_addr_bh1750[index]);
|
||||
break;
|
||||
case SENSOR_MAX44009:
|
||||
variable_item_set_current_value_text(item, device_addr_max44009[index]);
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %ld", app->config->sensor_type);
|
||||
return;
|
||||
}
|
||||
// variable_item_set_current_value_text(item, device_addr[index]);
|
||||
|
||||
LightMeterConfig* config = app->config;
|
||||
config->device_addr = index;
|
||||
lightmeter_app_set_config(app, config);
|
||||
|
||||
lightmeter_app_i2c_init_sensor(app);
|
||||
}
|
||||
|
||||
static void sensor_type_cb(VariableItem* item) {
|
||||
LightMeterApp* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
@@ -141,6 +213,9 @@ static void sensor_type_cb(VariableItem* item) {
|
||||
|
||||
LightMeterConfig* config = app->config;
|
||||
config->sensor_type = index;
|
||||
|
||||
update_item_addr(app);
|
||||
|
||||
lightmeter_app_set_config(app, config);
|
||||
}
|
||||
|
||||
@@ -195,6 +270,36 @@ void lightmeter_scene_config_on_enter(void* context) {
|
||||
variable_item_set_current_value_index(item, config->sensor_type);
|
||||
variable_item_set_current_value_text(item, sensor_type[config->sensor_type]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
var_item_list,
|
||||
"Resolution",
|
||||
COUNT_OF(measurement_resolution),
|
||||
measurement_resolution_cb,
|
||||
app);
|
||||
variable_item_set_current_value_index(item, config->measurement_resolution);
|
||||
variable_item_set_current_value_text(
|
||||
item, measurement_resolution[config->measurement_resolution]);
|
||||
|
||||
switch(config->sensor_type) {
|
||||
case SENSOR_BH1750:
|
||||
item = variable_item_list_add(
|
||||
var_item_list, "I2C address", COUNT_OF(device_addr_bh1750), device_addr_cb, app);
|
||||
variable_item_set_current_value_index(item, config->device_addr);
|
||||
variable_item_set_current_value_text(item, device_addr_bh1750[config->device_addr]);
|
||||
break;
|
||||
case SENSOR_MAX44009:
|
||||
item = variable_item_list_add(
|
||||
var_item_list, "I2C address", COUNT_OF(device_addr_max44009), device_addr_cb, app);
|
||||
variable_item_set_current_value_index(item, config->device_addr);
|
||||
variable_item_set_current_value_text(item, device_addr_max44009[config->device_addr]);
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %ld", config->sensor_type);
|
||||
return;
|
||||
}
|
||||
app->var_item_addr = item;
|
||||
update_item_addr(app);
|
||||
|
||||
item = variable_item_list_add(var_item_list, "Help and Pinout", 0, NULL, NULL);
|
||||
item = variable_item_list_add(var_item_list, "About", 0, NULL, NULL);
|
||||
|
||||
@@ -235,4 +340,5 @@ void lightmeter_scene_config_on_exit(void* context) {
|
||||
main_view_set_nd(app->main_view, app->config->nd);
|
||||
main_view_set_dome(app->main_view, app->config->dome);
|
||||
main_view_set_lux_only(app->main_view, app->config->lux_only);
|
||||
main_view_set_measurement_resolution(app->main_view, app->config->measurement_resolution);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ void lightmeter_scene_help_on_enter(void* context) {
|
||||
temp_str = furi_string_alloc();
|
||||
furi_string_printf(
|
||||
temp_str,
|
||||
"App works with BH1750 and MAX44409 ambient light sensor connected via I2C interface\n\n");
|
||||
"App works with BH1750/MAX44009\nambient light sensor\nconnected via I2C interface\n\n");
|
||||
furi_string_cat(temp_str, "\e#Pinout:\r\n");
|
||||
furi_string_cat(
|
||||
temp_str,
|
||||
@@ -15,6 +15,12 @@ void lightmeter_scene_help_on_enter(void* context) {
|
||||
" GND: GND\r\n"
|
||||
" SDA: 15 [C1]\r\n"
|
||||
" SCL: 16 [C0]\r\n");
|
||||
furi_string_cat(temp_str, "\r\n\e#Resolutions:\r\n");
|
||||
furi_string_cat(
|
||||
temp_str,
|
||||
"Low: 4.0lx (16ms, 0-54k)\r\n"
|
||||
"High: 1.0lx (120ms, 0-54k)\r\n"
|
||||
"High2: 0.5lx (120ms, 0-27k)\r\n");
|
||||
|
||||
widget_add_text_scroll_element(app->widget, 0, 0, 128, 64, furi_string_get_cstr(temp_str));
|
||||
furi_string_free(temp_str);
|
||||
|
||||
@@ -6,11 +6,24 @@ static void lightmeter_scene_main_on_left(void* context) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, LightMeterAppCustomEventConfig);
|
||||
}
|
||||
|
||||
static void lightmeter_scene_main_on_right(void* context) {
|
||||
LightMeterApp* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, LightMeterAppCustomEventReset);
|
||||
}
|
||||
|
||||
void lightmeter_scene_main_on_enter(void* context) {
|
||||
LightMeterApp* app = context;
|
||||
|
||||
lightmeter_app_i2c_init_sensor(context);
|
||||
variable_item_list_reset(app->var_item_list);
|
||||
main_view_set_iso(app->main_view, app->config->iso);
|
||||
main_view_set_nd(app->main_view, app->config->nd);
|
||||
main_view_set_dome(app->main_view, app->config->dome);
|
||||
main_view_set_lux_only(app->main_view, app->config->lux_only);
|
||||
main_view_set_measurement_resolution(app->main_view, app->config->measurement_resolution);
|
||||
|
||||
lightmeter_main_view_set_left_callback(app->main_view, lightmeter_scene_main_on_left, app);
|
||||
lightmeter_main_view_set_right_callback(app->main_view, lightmeter_scene_main_on_right, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LightMeterAppViewMainView);
|
||||
}
|
||||
|
||||
@@ -24,6 +37,9 @@ bool lightmeter_scene_main_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.event == LightMeterAppCustomEventConfig) {
|
||||
scene_manager_next_scene(app->scene_manager, LightMeterAppSceneConfig);
|
||||
response = true;
|
||||
} else if(event.event == LightMeterAppCustomEventReset) {
|
||||
lightmeter_app_reset_callback(app);
|
||||
response = true;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -40,5 +56,5 @@ bool lightmeter_scene_main_on_event(void* context, SceneManagerEvent event) {
|
||||
}
|
||||
|
||||
void lightmeter_scene_main_on_exit(void* context) {
|
||||
lightmeter_app_i2c_deinit_sensor(context);
|
||||
UNUSED(context);
|
||||
}
|
||||
|
||||
+81
-3
@@ -1,4 +1,5 @@
|
||||
#include "main_view.h"
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <gui/elements.h>
|
||||
@@ -72,6 +73,7 @@ const float speed_numbers[] = {
|
||||
struct MainView {
|
||||
View* view;
|
||||
LightMeterMainViewButtonCallback cb_left;
|
||||
LightMeterMainViewButtonCallback cb_right;
|
||||
void* cb_context;
|
||||
};
|
||||
|
||||
@@ -90,6 +92,21 @@ void lightmeter_main_view_set_left_callback(
|
||||
true);
|
||||
}
|
||||
|
||||
void lightmeter_main_view_set_right_callback(
|
||||
MainView* lightmeter_main_view,
|
||||
LightMeterMainViewButtonCallback callback,
|
||||
void* context) {
|
||||
with_view_model(
|
||||
lightmeter_main_view->view,
|
||||
MainViewModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
lightmeter_main_view->cb_right = callback;
|
||||
lightmeter_main_view->cb_context = context;
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static void main_view_draw_callback(Canvas* canvas, void* context) {
|
||||
furi_assert(context);
|
||||
MainViewModel* model = context;
|
||||
@@ -125,6 +142,7 @@ static void main_view_draw_callback(Canvas* canvas, void* context) {
|
||||
// draw mode indicator
|
||||
draw_mode_indicator(canvas, model);
|
||||
} else {
|
||||
elements_button_right(canvas, "Reset");
|
||||
draw_lux_only_mode(canvas, model);
|
||||
}
|
||||
}
|
||||
@@ -190,6 +208,11 @@ static bool main_view_input_callback(InputEvent* event, void* context) {
|
||||
main_view->cb_left(main_view->cb_context);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event->type == InputTypeShort && event->key == InputKeyRight) {
|
||||
if(main_view->cb_right) {
|
||||
main_view->cb_right(main_view->cb_context);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event->type == InputTypeShort && event->key == InputKeyBack) {
|
||||
} else {
|
||||
main_view_process(main_view, event);
|
||||
@@ -224,7 +247,22 @@ View* main_view_get_view(MainView* main_view) {
|
||||
void main_view_set_lux(MainView* main_view, float val) {
|
||||
furi_assert(main_view);
|
||||
with_view_model(
|
||||
main_view->view, MainViewModel * model, { model->lux = val; }, true);
|
||||
main_view->view,
|
||||
MainViewModel * model,
|
||||
{
|
||||
model->lux = val;
|
||||
model->peakLux = fmax(model->peakLux, val);
|
||||
|
||||
model->luxHistogram[model->luxHistogramIndex++] = val;
|
||||
model->luxHistogramIndex %= LUX_HISTORGRAM_LENGTH;
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void main_view_reset_lux(MainView* main_view) {
|
||||
furi_assert(main_view);
|
||||
with_view_model(
|
||||
main_view->view, MainViewModel * model, { model->peakLux = 0; }, true);
|
||||
}
|
||||
|
||||
void main_view_set_EV(MainView* main_view, float val) {
|
||||
@@ -275,6 +313,27 @@ void main_view_set_lux_only(MainView* main_view, bool lux_only) {
|
||||
main_view->view, MainViewModel * model, { model->lux_only = lux_only; }, true);
|
||||
}
|
||||
|
||||
void main_view_set_measurement_resolution(MainView* main_view, int measurement_resolution) {
|
||||
furi_assert(main_view);
|
||||
with_view_model(
|
||||
main_view->view,
|
||||
MainViewModel * model,
|
||||
{ model->measurement_resolution = measurement_resolution; },
|
||||
true);
|
||||
}
|
||||
|
||||
void main_view_set_device_addr(MainView* main_view, int device_addr) {
|
||||
furi_assert(main_view);
|
||||
with_view_model(
|
||||
main_view->view, MainViewModel * model, { model->device_addr = device_addr; }, true);
|
||||
}
|
||||
|
||||
void main_view_set_sensor_type(MainView* main_view, int sensor_type) {
|
||||
furi_assert(main_view);
|
||||
with_view_model(
|
||||
main_view->view, MainViewModel * model, { model->sensor_type = sensor_type; }, true);
|
||||
}
|
||||
|
||||
bool main_view_get_dome(MainView* main_view) {
|
||||
furi_assert(main_view);
|
||||
bool val = false;
|
||||
@@ -462,9 +521,28 @@ void draw_lux_only_mode(Canvas* canvas, MainViewModel* context) {
|
||||
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
snprintf(str, sizeof(str), "%.0f", (double)model->lux);
|
||||
canvas_draw_str_aligned(canvas, 80, 32, AlignRight, AlignCenter, str);
|
||||
canvas_draw_str_aligned(canvas, 80, 22, AlignRight, AlignCenter, str);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 85, 39, AlignLeft, AlignBottom, "Lux");
|
||||
canvas_draw_str_aligned(canvas, 85, 29, AlignLeft, AlignBottom, "Lux now");
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
snprintf(str, sizeof(str), "%.0f", (double)model->peakLux);
|
||||
canvas_draw_str_aligned(canvas, 80, 39, AlignRight, AlignCenter, str);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 85, 43, AlignLeft, AlignBottom, "Lux peak");
|
||||
|
||||
for(int i = 0; i < LUX_HISTORGRAM_LENGTH; i++) {
|
||||
float lux =
|
||||
model->luxHistogram[(i + model->luxHistogramIndex) % LUX_HISTORGRAM_LENGTH];
|
||||
int barHeight = log10(lux) / log10(LUX_HISTORGRAM_LOGBASE);
|
||||
canvas_draw_line(
|
||||
canvas,
|
||||
LUX_HISTORGRAM_LEFT + i,
|
||||
LUX_HISTORGRAM_BOTTOM,
|
||||
LUX_HISTORGRAM_LEFT + i,
|
||||
LUX_HISTORGRAM_BOTTOM - barHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,18 @@
|
||||
#include "lightmeter_icons.h"
|
||||
#include "../../lightmeter_config.h"
|
||||
|
||||
/* log base 1.4 and 12 pixels cut off
|
||||
makes it show values approx 65-65k
|
||||
with reasonable resolution in 1-10k range
|
||||
on 20px of screen height */
|
||||
#define LUX_HISTORGRAM_LOGBASE 1.4
|
||||
#define LUX_HISTORGRAM_BOTTOM 64 + 12
|
||||
|
||||
/* 40 pixels between 45th and 85th
|
||||
between left and right button labels */
|
||||
#define LUX_HISTORGRAM_LEFT 45
|
||||
#define LUX_HISTORGRAM_LENGTH 40
|
||||
|
||||
typedef struct MainView MainView;
|
||||
|
||||
typedef enum {
|
||||
@@ -17,6 +29,7 @@ typedef struct {
|
||||
uint8_t recv[2];
|
||||
MainViewMode current_mode;
|
||||
float lux;
|
||||
float peakLux;
|
||||
float EV;
|
||||
float aperture_val;
|
||||
float speed_val;
|
||||
@@ -28,6 +41,12 @@ typedef struct {
|
||||
int speed;
|
||||
bool dome;
|
||||
bool lux_only;
|
||||
int measurement_resolution;
|
||||
int device_addr;
|
||||
int sensor_type;
|
||||
|
||||
float luxHistogram[LUX_HISTORGRAM_LENGTH];
|
||||
int luxHistogramIndex;
|
||||
} MainViewModel;
|
||||
|
||||
typedef void (*LightMeterMainViewButtonCallback)(void* context);
|
||||
@@ -37,6 +56,11 @@ void lightmeter_main_view_set_left_callback(
|
||||
LightMeterMainViewButtonCallback callback,
|
||||
void* context);
|
||||
|
||||
void lightmeter_main_view_set_right_callback(
|
||||
MainView* lightmeter_main_view,
|
||||
LightMeterMainViewButtonCallback callback,
|
||||
void* context);
|
||||
|
||||
MainView* main_view_alloc();
|
||||
|
||||
void main_view_free(MainView* main_view);
|
||||
@@ -45,6 +69,8 @@ View* main_view_get_view(MainView* main_view);
|
||||
|
||||
void main_view_set_lux(MainView* main_view, float val);
|
||||
|
||||
void main_view_reset_lux(MainView* main_view);
|
||||
|
||||
void main_view_set_EV(MainView* main_view_, float val);
|
||||
|
||||
void main_view_set_response(MainView* main_view_, bool val);
|
||||
@@ -61,6 +87,12 @@ void main_view_set_dome(MainView* main_view, bool val);
|
||||
|
||||
void main_view_set_lux_only(MainView* main_view, bool val);
|
||||
|
||||
void main_view_set_measurement_resolution(MainView* main_view, int val);
|
||||
|
||||
void main_view_set_device_addr(MainView* main_view, int addr);
|
||||
|
||||
void main_view_set_sensor_type(MainView* main_view, int sensor_type);
|
||||
|
||||
bool main_view_get_dome(MainView* main_view);
|
||||
|
||||
void draw_top_row(Canvas* canvas, MainViewModel* context);
|
||||
|
||||
+12
-4
@@ -2,13 +2,20 @@
|
||||
#include <math.h>
|
||||
#include <furi.h>
|
||||
|
||||
uint8_t max44009_addr = MAX44009_ADDR;
|
||||
|
||||
void max44009_init() {
|
||||
furi_hal_i2c_acquire(I2C_BUS);
|
||||
furi_hal_i2c_write_reg_8(I2C_BUS, MAX44009_ADDR,
|
||||
MAX44009_REG_CONFIG, MAX44009_REG_CONFIG_CONT_MODE, I2C_TIMEOUT);
|
||||
furi_hal_i2c_write_reg_8(
|
||||
I2C_BUS, max44009_addr, MAX44009_REG_CONFIG, MAX44009_REG_CONFIG_CONT_MODE, I2C_TIMEOUT);
|
||||
furi_hal_i2c_release(I2C_BUS);
|
||||
}
|
||||
|
||||
void max44009_init_with_addr(uint8_t addr) {
|
||||
max44009_addr = (addr << 1);
|
||||
return max44009_init();
|
||||
}
|
||||
|
||||
int max44009_read_light(float* result) {
|
||||
uint8_t data_one = 0;
|
||||
uint8_t exp, mantissa;
|
||||
@@ -18,10 +25,11 @@ int max44009_read_light(float* result) {
|
||||
furi_hal_i2c_read_reg_8(I2C_BUS, MAX44009_ADDR, MAX44009_REG_LUX_HI, &data_one, I2C_TIMEOUT);
|
||||
exp = (data_one & MAX44009_REG_LUX_HI_EXP_MASK) >> 4;
|
||||
mantissa = (data_one & MAX44009_REG_LUX_HI_MANT_HI_MASK) << 4;
|
||||
status = furi_hal_i2c_read_reg_8(I2C_BUS, MAX44009_ADDR, MAX44009_REG_LUX_LO, &data_one, I2C_TIMEOUT);
|
||||
status = furi_hal_i2c_read_reg_8(
|
||||
I2C_BUS, MAX44009_ADDR, MAX44009_REG_LUX_LO, &data_one, I2C_TIMEOUT);
|
||||
mantissa |= (data_one & MAX44009_REG_LUX_LO_MANT_LO_MASK);
|
||||
furi_hal_i2c_release(I2C_BUS);
|
||||
*result = (float)pow(2, exp) * mantissa * 0.045;
|
||||
FURI_LOG_D("MAX44009", "exp %d, mant %d, lux %f", exp, mantissa, (double)*result);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,5 @@
|
||||
#define MAX44009_REG_INT_TIME 0x07
|
||||
|
||||
void max44009_init();
|
||||
void max44009_init_with_addr(uint8_t addr);
|
||||
int max44009_read_light(float* result);
|
||||
|
||||
+75
-4
@@ -34,11 +34,35 @@ LightMeterApp* lightmeter_app_alloc(uint32_t first_scene) {
|
||||
app->config->aperture = DEFAULT_APERTURE;
|
||||
app->config->dome = DEFAULT_DOME;
|
||||
app->config->backlight = DEFAULT_BACKLIGHT;
|
||||
app->config->measurement_resolution = HIGH_RES;
|
||||
app->config->device_addr = ADDR_LOW;
|
||||
app->config->lux_only = LUX_ONLY_OFF;
|
||||
|
||||
// Records
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
app->storage = furi_record_open(RECORD_STORAGE);
|
||||
app->notifications = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
app->cfg_path = furi_string_alloc();
|
||||
furi_string_printf(app->cfg_path, "%s/%s", APP_PATH_DIR, APP_PATH_CFG);
|
||||
|
||||
FlipperFormat* cfg_fmt = flipper_format_file_alloc(app->storage);
|
||||
if(flipper_format_file_open_existing(cfg_fmt, furi_string_get_cstr(app->cfg_path))) {
|
||||
flipper_format_read_int32(cfg_fmt, "iso", &app->config->iso, 1);
|
||||
flipper_format_read_int32(cfg_fmt, "aperture", &app->config->aperture, 1);
|
||||
flipper_format_read_int32(cfg_fmt, "dome", &app->config->dome, 1);
|
||||
flipper_format_read_int32(cfg_fmt, "backlight", &app->config->backlight, 1);
|
||||
flipper_format_read_int32(
|
||||
cfg_fmt, "measurement_resolution", &app->config->measurement_resolution, 1);
|
||||
flipper_format_read_int32(cfg_fmt, "lux_only", &app->config->lux_only, 1);
|
||||
flipper_format_read_int32(cfg_fmt, "device_addr", &app->config->device_addr, 1);
|
||||
flipper_format_read_int32(cfg_fmt, "sensor_type", &app->config->sensor_type, 1);
|
||||
}
|
||||
flipper_format_free(cfg_fmt);
|
||||
|
||||
// Sensor
|
||||
lightmeter_app_i2c_init_sensor(app);
|
||||
|
||||
// View dispatcher
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
app->scene_manager = scene_manager_alloc(&lightmeter_scene_handlers, app);
|
||||
@@ -110,8 +134,11 @@ void lightmeter_app_free(LightMeterApp* app) {
|
||||
app->notifications,
|
||||
&sequence_display_backlight_enforce_auto); // set backlight back to auto
|
||||
}
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
|
||||
bh1750_set_power_state(0);
|
||||
|
||||
free(app->config);
|
||||
free(app);
|
||||
}
|
||||
@@ -129,6 +156,24 @@ void lightmeter_app_set_config(LightMeterApp* context, LightMeterConfig* config)
|
||||
LightMeterApp* app = context;
|
||||
|
||||
app->config = config;
|
||||
storage_common_mkdir(app->storage, APP_PATH_DIR);
|
||||
|
||||
FlipperFormat* cfg_fmt = flipper_format_file_alloc(app->storage);
|
||||
if(flipper_format_file_open_always(cfg_fmt, furi_string_get_cstr(app->cfg_path))) {
|
||||
flipper_format_write_header_cstr(cfg_fmt, "lightmeter", 1);
|
||||
|
||||
flipper_format_write_int32(cfg_fmt, "iso", &(app->config->iso), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "nd", &(app->config->nd), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "aperture", &(app->config->aperture), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "dome", &(app->config->dome), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "backlight", &(app->config->backlight), 1);
|
||||
flipper_format_write_int32(
|
||||
cfg_fmt, "measurement_resolution", &(app->config->measurement_resolution), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "lux_only", &(app->config->lux_only), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "device_addr", &(app->config->device_addr), 1);
|
||||
flipper_format_write_int32(cfg_fmt, "sensor_type", &(app->config->sensor_type), 1);
|
||||
}
|
||||
flipper_format_free(cfg_fmt);
|
||||
}
|
||||
|
||||
void lightmeter_app_i2c_init_sensor(LightMeterApp* context) {
|
||||
@@ -136,14 +181,34 @@ void lightmeter_app_i2c_init_sensor(LightMeterApp* context) {
|
||||
switch(app->config->sensor_type) {
|
||||
case SENSOR_BH1750:
|
||||
bh1750_set_power_state(1);
|
||||
bh1750_init();
|
||||
switch(app->config->device_addr) {
|
||||
case ADDR_HIGH:
|
||||
bh1750_init_with_addr(0x5C);
|
||||
break;
|
||||
case ADDR_LOW:
|
||||
bh1750_init_with_addr(0x23);
|
||||
break;
|
||||
default:
|
||||
bh1750_init_with_addr(0x23);
|
||||
break;
|
||||
}
|
||||
bh1750_set_mode(ONETIME_HIGH_RES_MODE);
|
||||
break;
|
||||
case SENSOR_MAX44009:
|
||||
max44009_init();
|
||||
switch(app->config->device_addr) {
|
||||
case ADDR_HIGH:
|
||||
max44009_init_with_addr(0x4B);
|
||||
break;
|
||||
case ADDR_LOW:
|
||||
max44009_init_with_addr(0x4A);
|
||||
break;
|
||||
default:
|
||||
max44009_init_with_addr(0x4A);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %d", app->config->sensor_type);
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %ld", app->config->sensor_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -158,7 +223,7 @@ void lightmeter_app_i2c_deinit_sensor(LightMeterApp* context) {
|
||||
// nothing
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %d", app->config->sensor_type);
|
||||
FURI_LOG_E(TAG, "Invalid sensor type %ld", app->config->sensor_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -186,3 +251,9 @@ void lightmeter_app_i2c_callback(LightMeterApp* context) {
|
||||
main_view_set_EV(app->main_view, EV);
|
||||
main_view_set_response(app->main_view, response);
|
||||
}
|
||||
|
||||
void lightmeter_app_reset_callback(LightMeterApp* context) {
|
||||
LightMeterApp* app = context;
|
||||
|
||||
main_view_reset_lux(app->main_view);
|
||||
}
|
||||
|
||||
+24
-7
@@ -3,6 +3,9 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <stream/stream.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
@@ -20,14 +23,19 @@
|
||||
#include <BH1750.h>
|
||||
#include <MAX44009.h>
|
||||
|
||||
#define APP_PATH_DIR STORAGE_APP_DATA_PATH_PREFIX
|
||||
#define APP_PATH_CFG "config.txt"
|
||||
|
||||
typedef struct {
|
||||
int iso;
|
||||
int nd;
|
||||
int aperture;
|
||||
int dome;
|
||||
int backlight;
|
||||
int lux_only;
|
||||
int sensor_type;
|
||||
int32_t iso;
|
||||
int32_t nd;
|
||||
int32_t aperture;
|
||||
int32_t dome;
|
||||
int32_t backlight;
|
||||
int32_t lux_only;
|
||||
int32_t sensor_type;
|
||||
int32_t measurement_resolution;
|
||||
int32_t device_addr;
|
||||
} LightMeterConfig;
|
||||
|
||||
typedef struct {
|
||||
@@ -36,9 +44,13 @@ typedef struct {
|
||||
ViewDispatcher* view_dispatcher;
|
||||
MainView* main_view;
|
||||
VariableItemList* var_item_list;
|
||||
VariableItem* var_item_addr;
|
||||
LightMeterConfig* config;
|
||||
NotificationApp* notifications;
|
||||
Widget* widget;
|
||||
|
||||
Storage* storage;
|
||||
FuriString* cfg_path;
|
||||
} LightMeterApp;
|
||||
|
||||
typedef enum {
|
||||
@@ -50,6 +62,7 @@ typedef enum {
|
||||
} LightMeterAppView;
|
||||
|
||||
typedef enum {
|
||||
LightMeterAppCustomEventReset,
|
||||
LightMeterAppCustomEventConfig,
|
||||
LightMeterAppCustomEventHelp,
|
||||
LightMeterAppCustomEventAbout,
|
||||
@@ -58,5 +71,9 @@ typedef enum {
|
||||
void lightmeter_app_set_config(LightMeterApp* context, LightMeterConfig* config);
|
||||
|
||||
void lightmeter_app_i2c_init_sensor(LightMeterApp* context);
|
||||
|
||||
void lightmeter_app_i2c_deinit_sensor(LightMeterApp* context);
|
||||
|
||||
void lightmeter_app_i2c_callback(LightMeterApp* context);
|
||||
|
||||
void lightmeter_app_reset_callback(LightMeterApp* context);
|
||||
|
||||
+12
-1
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define LM_VERSION_APP "1.1"
|
||||
#define LM_VERSION_APP "1.2"
|
||||
#define LM_DEVELOPED "Oleksii Kutuzov"
|
||||
#define LM_GITHUB "https://github.com/oleksiikutuzov/flipperzero-lightmeter"
|
||||
|
||||
@@ -105,6 +105,17 @@ typedef enum {
|
||||
LUX_ONLY_ON,
|
||||
} LightMeterLuxOnlyMode;
|
||||
|
||||
typedef enum {
|
||||
LOW_RES,
|
||||
HIGH_RES,
|
||||
HIGH_RES2,
|
||||
} LightMeterMeterMode;
|
||||
|
||||
typedef enum {
|
||||
ADDR_LOW,
|
||||
ADDR_HIGH,
|
||||
} LightMeterMeterAddr;
|
||||
|
||||
typedef enum {
|
||||
SENSOR_BH1750,
|
||||
SENSOR_MAX44009,
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#include <cc1101.h>
|
||||
#include <cc1101_regs.h>
|
||||
/* ========================== DATA RATE SETTINGS ===============================
|
||||
*
|
||||
* This is how to configure registers MDMCFG3 and MDMCFG4.
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
* See the LICENSE file for information about the license. */
|
||||
|
||||
#include "app.h"
|
||||
#include <cc1101.h>
|
||||
#include <cc1101_regs.h>
|
||||
|
||||
static void direct_sampling_timer_start(ProtoViewApp* app);
|
||||
static void direct_sampling_timer_stop(ProtoViewApp* app);
|
||||
|
||||
+1
-6
@@ -497,7 +497,6 @@ int32_t solitaire_app(void* p) {
|
||||
for(bool processing = true; processing;) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 150);
|
||||
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
|
||||
bool hadChange = false;
|
||||
if(event_status == FuriStatusOk) {
|
||||
if(event.type == EventTypeKey) {
|
||||
if(event.input.type == InputTypeLong) {
|
||||
@@ -528,7 +527,6 @@ int32_t solitaire_app(void* p) {
|
||||
game_state->state = GameStatePlay;
|
||||
init(game_state);
|
||||
} else {
|
||||
hadChange = true;
|
||||
game_state->input = event.input.key;
|
||||
}
|
||||
break;
|
||||
@@ -546,11 +544,8 @@ int32_t solitaire_app(void* p) {
|
||||
processing = game_state->processing;
|
||||
game_state->input = InputKeyMAX;
|
||||
}
|
||||
} else {
|
||||
//FURI_LOG_W(APP_NAME, "osMessageQueue: event timeout");
|
||||
// event timeout
|
||||
}
|
||||
if(hadChange || game_state->state == GameStateAnimate) view_port_update(view_port);
|
||||
view_port_update(view_port);
|
||||
furi_mutex_release(game_state->mutex);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ App(
|
||||
order=12,
|
||||
fap_icon="spectrum_10px.png",
|
||||
fap_category="Sub-GHz",
|
||||
fap_author="@xMasterX & @theY4Kman (original by @jolcese)",
|
||||
fap_version="1.0",
|
||||
fap_description="Shows received signals on spectrum, not actual analyzer, more like a demo app",
|
||||
fap_author="@xMasterX & @theY4Kman & @ALEEF02 (original by @jolcese)",
|
||||
fap_version="1.1",
|
||||
fap_description="Displays a spectrogram chart to visually represent RF signals around you.",
|
||||
)
|
||||
|
||||
+118
-52
@@ -13,6 +13,7 @@
|
||||
typedef struct {
|
||||
uint32_t center_freq;
|
||||
uint8_t width;
|
||||
uint8_t modulation;
|
||||
uint8_t band;
|
||||
uint8_t vscroll;
|
||||
|
||||
@@ -20,6 +21,7 @@ typedef struct {
|
||||
uint32_t spacing;
|
||||
|
||||
bool mode_change;
|
||||
bool modulation_change;
|
||||
|
||||
float max_rssi;
|
||||
uint8_t max_rssi_dec;
|
||||
@@ -85,6 +87,7 @@ void spectrum_analyzer_draw_scale(Canvas* canvas, const SpectrumAnalyzerModel* m
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
switch(model->width) {
|
||||
case PRECISE:
|
||||
case ULTRANARROW:
|
||||
snprintf(temp_str, 18, "%.1f", ((double)tag_left) / 1000);
|
||||
canvas_draw_str_aligned(canvas, FREQ_START_X, 63, AlignCenter, AlignBottom, temp_str);
|
||||
snprintf(temp_str, 18, "%.1f", ((double)tag_center) / 1000);
|
||||
@@ -147,6 +150,24 @@ static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
|
||||
snprintf(tmp_str, 21, "Mode: %s", temp_mode_str);
|
||||
canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str);
|
||||
}
|
||||
|
||||
if(model->modulation_change) {
|
||||
char temp_mod_str[12];
|
||||
switch(model->modulation) {
|
||||
case NARROW_MODULATION:
|
||||
strncpy(temp_mod_str, "NARROW", 12);
|
||||
break;
|
||||
default:
|
||||
strncpy(temp_mod_str, "DEFAULT", 12);
|
||||
break;
|
||||
}
|
||||
|
||||
// Current modulation label
|
||||
char tmp_str[27];
|
||||
snprintf(tmp_str, 27, "Modulation: %s", temp_mod_str);
|
||||
canvas_draw_str_aligned(canvas, 127, 4, AlignRight, AlignTop, tmp_str);
|
||||
}
|
||||
|
||||
// Draw cross and label
|
||||
if(model->max_rssi > PEAK_THRESHOLD) {
|
||||
// Compress height to max of 64 values (255>>2)
|
||||
@@ -194,8 +215,8 @@ static void spectrum_analyzer_render_callback(Canvas* const canvas, void* ctx) {
|
||||
|
||||
static void spectrum_analyzer_input_callback(InputEvent* input_event, void* ctx) {
|
||||
SpectrumAnalyzer* spectrum_analyzer = ctx;
|
||||
// Only handle short presses
|
||||
if(input_event->type == InputTypeShort) {
|
||||
// Handle short and long presses
|
||||
if(input_event->type == InputTypeShort || input_event->type == InputTypeLong) {
|
||||
furi_message_queue_put(spectrum_analyzer->event_queue, input_event, FuriWaitForever);
|
||||
}
|
||||
}
|
||||
@@ -376,6 +397,7 @@ SpectrumAnalyzer* spectrum_analyzer_alloc() {
|
||||
|
||||
model->center_freq = DEFAULT_FREQ;
|
||||
model->width = WIDE;
|
||||
model->modulation = DEFAULT_MODULATION;
|
||||
model->band = BAND_400;
|
||||
|
||||
model->vscroll = DEFAULT_VSCROLL;
|
||||
@@ -463,70 +485,114 @@ int32_t spectrum_analyzer_app(void* p) {
|
||||
case ULTRAWIDE:
|
||||
hstep = ULTRAWIDE_STEP;
|
||||
break;
|
||||
case PRECISE:
|
||||
hstep = PRECISE_STEP;
|
||||
break;
|
||||
default:
|
||||
hstep = WIDE_STEP;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input.key) {
|
||||
case InputKeyUp:
|
||||
model->vscroll = MAX(model->vscroll - vstep, MIN_VSCROLL);
|
||||
FURI_LOG_D("Spectrum", "Vscroll: %u", model->vscroll);
|
||||
break;
|
||||
case InputKeyDown:
|
||||
model->vscroll = MIN(model->vscroll + vstep, MAX_VSCROLL);
|
||||
FURI_LOG_D("Spectrum", "Vscroll: %u", model->vscroll);
|
||||
break;
|
||||
case InputKeyRight:
|
||||
model->center_freq += hstep;
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
model->center_freq -= hstep;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
break;
|
||||
case InputKeyOk: {
|
||||
switch(model->width) {
|
||||
case WIDE:
|
||||
model->width = NARROW;
|
||||
switch(input.type) {
|
||||
case InputTypeShort:
|
||||
switch(input.key) {
|
||||
case InputKeyUp:
|
||||
model->vscroll = MAX(model->vscroll - vstep, MIN_VSCROLL);
|
||||
FURI_LOG_D("Spectrum", "Vscroll: %u", model->vscroll);
|
||||
break;
|
||||
case NARROW:
|
||||
model->width = ULTRANARROW;
|
||||
case InputKeyDown:
|
||||
model->vscroll = MIN(model->vscroll + vstep, MAX_VSCROLL);
|
||||
FURI_LOG_D("Spectrum", "Vscroll: %u", model->vscroll);
|
||||
break;
|
||||
case ULTRANARROW:
|
||||
model->width = PRECISE;
|
||||
case InputKeyRight:
|
||||
model->center_freq += hstep;
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker,
|
||||
model->channel0_frequency,
|
||||
model->spacing,
|
||||
model->width);
|
||||
break;
|
||||
case PRECISE:
|
||||
model->width = ULTRAWIDE;
|
||||
case InputKeyLeft:
|
||||
model->center_freq -= hstep;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker,
|
||||
model->channel0_frequency,
|
||||
model->spacing,
|
||||
model->width);
|
||||
FURI_LOG_D("Spectrum", "center_freq: %lu", model->center_freq);
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
model->width = WIDE;
|
||||
case InputKeyOk: {
|
||||
switch(model->width) {
|
||||
case WIDE:
|
||||
model->width = NARROW;
|
||||
break;
|
||||
case NARROW:
|
||||
model->width = ULTRANARROW;
|
||||
break;
|
||||
case ULTRANARROW:
|
||||
model->width = PRECISE;
|
||||
break;
|
||||
case PRECISE:
|
||||
model->width = ULTRAWIDE;
|
||||
break;
|
||||
case ULTRAWIDE:
|
||||
model->width = WIDE;
|
||||
break;
|
||||
default:
|
||||
model->width = WIDE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
model->mode_change = true;
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
|
||||
furi_delay_ms(1000);
|
||||
|
||||
model->mode_change = false;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker,
|
||||
model->channel0_frequency,
|
||||
model->spacing,
|
||||
model->width);
|
||||
FURI_LOG_D("Spectrum", "Width: %u", model->width);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
exit_loop = true;
|
||||
break;
|
||||
default:
|
||||
model->width = WIDE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
model->mode_change = true;
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
|
||||
furi_delay_ms(1000);
|
||||
|
||||
model->mode_change = false;
|
||||
spectrum_analyzer_calculate_frequencies(model);
|
||||
spectrum_analyzer_worker_set_frequencies(
|
||||
spectrum_analyzer->worker, model->channel0_frequency, model->spacing, model->width);
|
||||
FURI_LOG_D("Spectrum", "Width: %u", model->width);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
exit_loop = true;
|
||||
case InputTypeLong:
|
||||
switch(input.key) {
|
||||
case InputKeyOk:
|
||||
FURI_LOG_D("Spectrum", "InputTypeLong");
|
||||
switch(model->modulation) {
|
||||
case NARROW_MODULATION:
|
||||
model->modulation = DEFAULT_MODULATION;
|
||||
break;
|
||||
case DEFAULT_MODULATION:
|
||||
default:
|
||||
model->modulation = NARROW_MODULATION;
|
||||
break;
|
||||
}
|
||||
|
||||
model->modulation_change = true;
|
||||
view_port_update(spectrum_analyzer->view_port);
|
||||
|
||||
furi_delay_ms(1000);
|
||||
|
||||
model->modulation_change = false;
|
||||
spectrum_analyzer_worker_set_modulation(
|
||||
spectrum_analyzer->worker, spectrum_analyzer->model->modulation);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* wide mode (default): 20 MHz on screen, 196 kHz per channel
|
||||
* narrow mode: 4 MHz on screen, 39 kHz per channel
|
||||
* ultranarrow mode: 2 MHz on screen, 19 kHz per channel
|
||||
* pricse mode: 400 KHz on screen, 3.92 kHz per channel
|
||||
* precise mode: 400 KHz on screen, 3.92 kHz per channel
|
||||
*/
|
||||
#define WIDE 0
|
||||
#define NARROW 1
|
||||
@@ -77,4 +77,8 @@
|
||||
#define MID_900 848000000
|
||||
|
||||
#define UPPER(a, b, c) ((((a) - (b) + ((c) / 2)) / (c)) * (c))
|
||||
#define LOWER(a, b, c) ((((a) + (b)) / (c)) * (c))
|
||||
#define LOWER(a, b, c) ((((a) + (b)) / (c)) * (c))
|
||||
|
||||
/* Modulation references */
|
||||
#define DEFAULT_MODULATION 0
|
||||
#define NARROW_MODULATION 1
|
||||
@@ -20,6 +20,7 @@ struct SpectrumAnalyzerWorker {
|
||||
uint32_t channel0_frequency;
|
||||
uint32_t spacing;
|
||||
uint8_t width;
|
||||
uint8_t modulation;
|
||||
float max_rssi;
|
||||
uint8_t max_rssi_dec;
|
||||
uint8_t max_rssi_channel;
|
||||
@@ -66,18 +67,45 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
subghz_devices_flush_rx(instance->radio_device);
|
||||
subghz_devices_set_rx(instance->radio_device);
|
||||
|
||||
const uint8_t radio_config[] = {
|
||||
// Default modulation
|
||||
const uint8_t default_modulation[] = {
|
||||
|
||||
/* Frequency Synthesizer Control */
|
||||
CC1101_FSCTRL0,
|
||||
0x00,
|
||||
CC1101_FSCTRL1,
|
||||
0x12,
|
||||
|
||||
CC1101_AGCCTRL2,
|
||||
0xC0,
|
||||
0x12, // IF = (26*10^6) / (2^10) * 0x12 = 304687.5 Hz
|
||||
|
||||
// Modem Configuration
|
||||
// CC1101_MDMCFG0,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG1,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG2,
|
||||
// 0x30, // Format ASK/OOK, No preamble/sync
|
||||
// CC1101_MDMCFG3,
|
||||
// 0x32, // Data rate is 121.399 kBaud
|
||||
CC1101_MDMCFG4,
|
||||
0x6C,
|
||||
0x6C, // Rx BW filter is 270.83 kHz
|
||||
|
||||
/* Frequency Offset Compensation Configuration */
|
||||
// CC1101_FOCCFG,
|
||||
// 0x18, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
|
||||
|
||||
/* Automatic Gain Control */
|
||||
// CC1101_AGCCTRL0,
|
||||
// 0x91, // 10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
|
||||
// CC1101_AGCCTRL1,
|
||||
// 0x0, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
|
||||
CC1101_AGCCTRL2,
|
||||
0xC0, // 03 - The 3 highest DVGA gain settings can not be used; 000 - MAX LNA+LNA2; 000 - MAIN_TARGET 24 dB
|
||||
|
||||
/* Frontend configuration */
|
||||
// CC1101_FREND0,
|
||||
// 0x11, // Adjusts current TX LO buffer + high is PATABLE[1]
|
||||
// CC1101_FREND1,
|
||||
// 0xB6, //
|
||||
|
||||
CC1101_TEST2,
|
||||
0x88,
|
||||
CC1101_TEST1,
|
||||
@@ -97,8 +125,69 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00};
|
||||
|
||||
// Narrow modulation
|
||||
const uint8_t narrow_modulation[] = {
|
||||
|
||||
/* Frequency Synthesizer Control */
|
||||
CC1101_FSCTRL0,
|
||||
0x00,
|
||||
};
|
||||
CC1101_FSCTRL1,
|
||||
0x00, // IF = (26*10^6) / (2^10) * 0x00 = 0 Hz
|
||||
|
||||
// Modem Configuration
|
||||
// CC1101_MDMCFG0,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG1,
|
||||
// 0x00, // Channel spacing is 25kHz
|
||||
// CC1101_MDMCFG2,
|
||||
// 0x30, // Format ASK/OOK, No preamble/sync
|
||||
// CC1101_MDMCFG3,
|
||||
// 0x32, // Data rate is 121.399 kBaud
|
||||
CC1101_MDMCFG4,
|
||||
0xFC, // Rx BW filter is 58.04 kHz
|
||||
|
||||
/* Frequency Offset Compensation Configuration */
|
||||
// CC1101_FOCCFG,
|
||||
// 0x18, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
|
||||
|
||||
/* Automatic Gain Control */
|
||||
CC1101_AGCCTRL0,
|
||||
0x30, // 00 - NO hysteresis, symmetric dead zone, high gain ; 11 - 32 samples agc; 00 - Normal AGC, 00 - 8dB boundary
|
||||
CC1101_AGCCTRL1,
|
||||
0x0, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
|
||||
CC1101_AGCCTRL2,
|
||||
0x84, // 02 - The 2 highest DVGA gain settings can not be used; 000 - MAX LNA+LNA2; 100 - MAIN_TARGET 36 dB
|
||||
|
||||
/* Frontend configuration */
|
||||
// CC1101_FREND0,
|
||||
// 0x11, // Adjusts current TX LO buffer + high is PATABLE[1]
|
||||
// CC1101_FREND1,
|
||||
// 0xB6, //
|
||||
|
||||
CC1101_TEST2,
|
||||
0x88,
|
||||
CC1101_TEST1,
|
||||
0x31,
|
||||
CC1101_TEST0,
|
||||
0x09,
|
||||
|
||||
/* End */
|
||||
0,
|
||||
0,
|
||||
|
||||
// ook_async_patable
|
||||
0x00,
|
||||
0xC0, // 12dBm 0xC0, 10dBm 0xC5, 7dBm 0xCD, 5dBm 0x86, 0dBm 0x50, -6dBm 0x37, -10dBm 0x26, -15dBm 0x1D, -20dBm 0x17, -30dBm 0x03
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00};
|
||||
|
||||
const uint8_t* modulations[] = {default_modulation, narrow_modulation};
|
||||
|
||||
while(instance->should_work) {
|
||||
furi_delay_ms(50);
|
||||
@@ -106,7 +195,12 @@ static int32_t spectrum_analyzer_worker_thread(void* context) {
|
||||
// FURI_LOG_T("SpectrumWorker", "spectrum_analyzer_worker_thread: Worker Loop");
|
||||
subghz_devices_idle(instance->radio_device);
|
||||
subghz_devices_load_preset(
|
||||
instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)radio_config);
|
||||
instance->radio_device,
|
||||
FuriHalSubGhzPresetCustom,
|
||||
(uint8_t*)modulations[instance->modulation]);
|
||||
//subghz_devices_load_preset(
|
||||
// instance->radio_device, FuriHalSubGhzPresetCustom, (uint8_t*)default_modulation);
|
||||
//furi_hal_subghz_load_custom_preset(modulations[instance->modulation]);
|
||||
|
||||
// TODO: Check filter!
|
||||
// spectrum_analyzer_worker_set_filter(instance);
|
||||
@@ -222,6 +316,15 @@ void spectrum_analyzer_worker_set_frequencies(
|
||||
instance->width = width;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_set_modulation(SpectrumAnalyzerWorker* instance, uint8_t modulation) {
|
||||
furi_assert(instance);
|
||||
|
||||
FURI_LOG_D(
|
||||
"SpectrumWorker", "spectrum_analyzer_worker_set_modulation - modulation = %u", modulation);
|
||||
|
||||
instance->modulation = modulation;
|
||||
}
|
||||
|
||||
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance) {
|
||||
FURI_LOG_D("Spectrum", "spectrum_analyzer_worker_start");
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ void spectrum_analyzer_worker_set_frequencies(
|
||||
uint32_t spacing,
|
||||
uint8_t width);
|
||||
|
||||
void spectrum_analyzer_worker_set_modulation(SpectrumAnalyzerWorker* instance, uint8_t modulation);
|
||||
|
||||
void spectrum_analyzer_worker_start(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
void spectrum_analyzer_worker_stop(SpectrumAnalyzerWorker* instance);
|
||||
|
||||
+51
-49
@@ -223,56 +223,58 @@ int32_t text_viewer_app(void* p) {
|
||||
text_viewer_read_file(text_viewer);
|
||||
|
||||
InputEvent input;
|
||||
while(furi_message_queue_get(text_viewer->input_queue, &input, FuriWaitForever) ==
|
||||
FuriStatusOk) {
|
||||
if(input.key == InputKeyBack) {
|
||||
break;
|
||||
} else if(input.key == InputKeyUp) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(text_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(text_viewer->model->file_offset > 0) {
|
||||
text_viewer->model->file_offset -= TEXT_VIEWER_BYTES_PER_LINE;
|
||||
if(!text_viewer_read_file(text_viewer)) break;
|
||||
while(1) {
|
||||
if(furi_message_queue_get(text_viewer->input_queue, &input, 100) == FuriStatusOk) {
|
||||
if(input.key == InputKeyBack) {
|
||||
break;
|
||||
} else if(input.key == InputKeyUp) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(text_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(text_viewer->model->file_offset > 0) {
|
||||
text_viewer->model->file_offset -= TEXT_VIEWER_BYTES_PER_LINE;
|
||||
if(!text_viewer_read_file(text_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(text_viewer->mutex);
|
||||
} else if(input.key == InputKeyDown) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(text_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
uint32_t last_byte_on_screen =
|
||||
text_viewer->model->file_offset + text_viewer->model->file_read_bytes;
|
||||
|
||||
if(text_viewer->model->file_size > last_byte_on_screen) {
|
||||
text_viewer->model->file_offset += TEXT_VIEWER_BYTES_PER_LINE;
|
||||
if(!text_viewer_read_file(text_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(text_viewer->mutex);
|
||||
} else if(input.key == InputKeyLeft) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(text_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
text_viewer->model->mode = !text_viewer->model->mode;
|
||||
furi_mutex_release(text_viewer->mutex);
|
||||
} else if(input.key == InputKeyRight) {
|
||||
FuriString* buffer;
|
||||
buffer = furi_string_alloc();
|
||||
furi_string_printf(
|
||||
buffer,
|
||||
"File path: %s\nFile size: %lu (0x%lX)",
|
||||
furi_string_get_cstr(file_path),
|
||||
text_viewer->model->file_size,
|
||||
text_viewer->model->file_size);
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(
|
||||
message, "Text Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_icon(message, &I_text_10px, 3, 2);
|
||||
dialog_message_set_text(
|
||||
message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop);
|
||||
dialog_message_set_buttons(message, NULL, NULL, "Back");
|
||||
dialog_message_show(dialogs, message);
|
||||
|
||||
furi_string_free(buffer);
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
furi_mutex_release(text_viewer->mutex);
|
||||
} else if(input.key == InputKeyDown) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(text_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
uint32_t last_byte_on_screen =
|
||||
text_viewer->model->file_offset + text_viewer->model->file_read_bytes;
|
||||
|
||||
if(text_viewer->model->file_size > last_byte_on_screen) {
|
||||
text_viewer->model->file_offset += TEXT_VIEWER_BYTES_PER_LINE;
|
||||
if(!text_viewer_read_file(text_viewer)) break;
|
||||
}
|
||||
furi_mutex_release(text_viewer->mutex);
|
||||
} else if(input.key == InputKeyLeft) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(text_viewer->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
text_viewer->model->mode = !text_viewer->model->mode;
|
||||
furi_mutex_release(text_viewer->mutex);
|
||||
} else if(input.key == InputKeyRight) {
|
||||
FuriString* buffer;
|
||||
buffer = furi_string_alloc();
|
||||
furi_string_printf(
|
||||
buffer,
|
||||
"File path: %s\nFile size: %lu (0x%lX)",
|
||||
furi_string_get_cstr(file_path),
|
||||
text_viewer->model->file_size,
|
||||
text_viewer->model->file_size);
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_header(message, "Text Viewer v1.1", 16, 2, AlignLeft, AlignTop);
|
||||
dialog_message_set_icon(message, &I_text_10px, 3, 2);
|
||||
dialog_message_set_text(
|
||||
message, furi_string_get_cstr(buffer), 3, 16, AlignLeft, AlignTop);
|
||||
dialog_message_set_buttons(message, NULL, NULL, "Back");
|
||||
dialog_message_show(dialogs, message);
|
||||
|
||||
furi_string_free(buffer);
|
||||
dialog_message_free(message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
}
|
||||
view_port_update(text_viewer->view_port);
|
||||
}
|
||||
|
||||
+14
-1
@@ -3,9 +3,19 @@ App(
|
||||
name="Authenticator",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="totp_app",
|
||||
requires=["gui", "cli", "dialogs", "storage", "input", "notification", "bt"],
|
||||
cdefines=["APP_TOTP"],
|
||||
requires=[
|
||||
"gui",
|
||||
"cli",
|
||||
"dialogs",
|
||||
"storage",
|
||||
"input",
|
||||
"notification",
|
||||
"bt"
|
||||
],
|
||||
stack_size=2 * 1024,
|
||||
order=20,
|
||||
fap_version="2.3",
|
||||
fap_author="Alexander Kopachov (@akopachov)",
|
||||
fap_description="Software-based TOTP authenticator for Flipper Zero device",
|
||||
fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",
|
||||
@@ -28,5 +38,8 @@ App(
|
||||
Lib(
|
||||
name="roll_value",
|
||||
),
|
||||
Lib(
|
||||
name="fonts",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
+1
-4
@@ -22,10 +22,7 @@ extern const char* TOTP_CLI_COLOR_INFO;
|
||||
#define TOTP_CLI_PRINTF(format, ...) printf(format, ##__VA_ARGS__)
|
||||
|
||||
#define TOTP_CLI_PRINTF_COLORFUL(color, format, ...) \
|
||||
printf("\e[%s", color); \
|
||||
printf(format, ##__VA_ARGS__); \
|
||||
printf("\e[0m"); \
|
||||
fflush(stdout)
|
||||
TOTP_CLI_PRINTF("\e[%s" format "\e[0m", color, ##__VA_ARGS__)
|
||||
|
||||
#define TOTP_CLI_PRINTF_ERROR(format, ...) \
|
||||
TOTP_CLI_PRINTF_COLORFUL(TOTP_CLI_COLOR_ERROR, format, ##__VA_ARGS__)
|
||||
|
||||
+34
-22
@@ -102,15 +102,22 @@ void totp_cli_command_add_docopt_options() {
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_ALGO_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_ALGO)) " Token hashing algorithm. Must be one of: " TOTP_TOKEN_ALGO_SHA1_NAME
|
||||
", " TOTP_TOKEN_ALGO_SHA256_NAME
|
||||
", " TOTP_TOKEN_ALGO_SHA512_NAME
|
||||
", " TOTP_TOKEN_ALGO_STEAM_NAME
|
||||
" " DOCOPT_DEFAULT(TOTP_TOKEN_ALGO_SHA1_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS)) " Number of digits to generate, one of: 5, 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
|
||||
TOTP_CLI_COMMAND_ARG_ALGO)) " Token hashing algorithm. Must be one of: " TOKEN_HASH_ALGO_SHA1_NAME
|
||||
", " TOKEN_HASH_ALGO_SHA256_NAME
|
||||
", " TOKEN_HASH_ALGO_SHA512_NAME
|
||||
", " TOKEN_HASH_ALGO_STEAM_NAME
|
||||
" " DOCOPT_DEFAULT(TOKEN_HASH_ALGO_SHA1_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(
|
||||
" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS)) " Number of digits to generate, one of: %" PRIu8
|
||||
", %" PRIu8 ", %" PRIu8
|
||||
" " DOCOPT_DEFAULT("%" PRIu8) "\r\n",
|
||||
TokenDigitsCountFive,
|
||||
TokenDigitsCountSix,
|
||||
TokenDigitsCountEight,
|
||||
TokenDigitsCountSix);
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX,
|
||||
@@ -120,27 +127,32 @@ void totp_cli_command_add_docopt_options() {
|
||||
" " DOCOPT_DEFAULT(
|
||||
PLAIN_TOKEN_ENCODING_BASE32_NAME) "\r\n");
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION)) " Token lifetime duration in seconds, between: 15 and 255 " DOCOPT_DEFAULT("30") "\r\n");
|
||||
TOTP_CLI_PRINTF(
|
||||
" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION)) " Token lifetime duration in seconds, between: %" PRIu8
|
||||
" and %" PRIu8
|
||||
" " DOCOPT_DEFAULT("%" PRIu8) "\r\n",
|
||||
TokenDurationMin,
|
||||
TokenDurationMax,
|
||||
TokenDurationDefault);
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
||||
TOTP_CLI_COMMAND_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n");
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)) " Token automation features to be enabled. Must be one of: " TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME
|
||||
", " TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
", " TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)) " Token automation features to be enabled. Must be one of: " TOKEN_AUTOMATION_FEATURE_NONE_NAME
|
||||
", " TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
", " TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
" " DOCOPT_DEFAULT(
|
||||
TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME
|
||||
" - No features\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
TOKEN_AUTOMATION_FEATURE_NONE_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_NONE_NAME " - No features\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME
|
||||
" - Type <Enter> key at the end of token input automation\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME
|
||||
" - Type <Tab> key at the end of token input automation\r\n");
|
||||
TOTP_CLI_PRINTF(" # " TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME
|
||||
TOTP_CLI_PRINTF(" # " TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME
|
||||
" - Type slower\r\n");
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -4,19 +4,21 @@
|
||||
#endif
|
||||
|
||||
// Include Bluetooth token input automation
|
||||
#ifndef TOTP_NO_BADBT_TYPE
|
||||
#define TOTP_BADBT_TYPE_ENABLED
|
||||
#endif
|
||||
|
||||
// Include token input automation icons on the main screen
|
||||
#ifndef TOTP_NO_AUTOMATION_ICONS
|
||||
#define TOTP_AUTOMATION_ICONS_ENABLED
|
||||
#endif
|
||||
|
||||
// List of compatible firmwares
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE 1
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV 2
|
||||
#define TOTP_FIRMWARE_UL_XFW 3 // XFW and UL now has same bluetooth mac/advname changing API
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE (1)
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV (2)
|
||||
#define TOTP_FIRMWARE_XTREME_UL (3)
|
||||
// End of list
|
||||
|
||||
// Target firmware to build for
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_UL_XFW
|
||||
|
||||
// Max custom fonts value
|
||||
#define MAX_CUSTOM_FONTS (9)
|
||||
#ifndef TOTP_TARGET_FIRMWARE
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_XTREME_UL
|
||||
#endif
|
||||
|
||||
+1
@@ -931,6 +931,7 @@ const FONT_CHAR_INFO _712Serif_24ptDescriptors[] = {
|
||||
|
||||
/* Font information for 7:12 Serif 24pt */
|
||||
const FONT_INFO _712Serif_24ptFontInfo = {
|
||||
"712 Serif",
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "available_fonts.h"
|
||||
#include "712serif/712serif.h"
|
||||
#include "bedstead/bedstead.h"
|
||||
#include "dpcomic/dpcomic.h"
|
||||
#include "funclimbing/funclimbing.h"
|
||||
#include "graph35pix/graph35pix.h"
|
||||
#include "karma_future/karma_future.h"
|
||||
#include "mode_nine/mode_nine.h"
|
||||
#include "pixelflag/pixelflag.h"
|
||||
#include "redhat_mono/redhat_mono.h"
|
||||
#include "zector/zector.h"
|
||||
|
||||
const FONT_INFO* const available_fonts[AVAILABLE_FONTS_COUNT] = {
|
||||
&modeNine_15ptFontInfo,
|
||||
&_712Serif_24ptFontInfo,
|
||||
&bedstead_17ptFontInfo,
|
||||
&dPComic_18ptFontInfo,
|
||||
&funclimbingDemo_18ptFontInfo,
|
||||
&graph35pix_12ptFontInfo,
|
||||
&karmaFuture_14ptFontInfo,
|
||||
&pixelFlag_18ptFontInfo,
|
||||
&redHatMono_16ptFontInfo,
|
||||
&zector_18ptFontInfo};
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "font_info.h"
|
||||
|
||||
#define AVAILABLE_FONTS_COUNT (10)
|
||||
|
||||
extern const FONT_INFO* const available_fonts[AVAILABLE_FONTS_COUNT];
|
||||
+1
@@ -1047,6 +1047,7 @@ const FONT_CHAR_INFO bedstead_17ptDescriptors[] = {
|
||||
|
||||
/* Font information for Bedstead 17pt */
|
||||
const FONT_INFO bedstead_17ptFontInfo = {
|
||||
"Bedstead",
|
||||
16, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -1105,6 +1105,7 @@ const FONT_CHAR_INFO dPComic_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for DPComic 18pt */
|
||||
const FONT_INFO dPComic_18ptFontInfo = {
|
||||
"DP Comic",
|
||||
17, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
Vendored
+1
-1
@@ -14,11 +14,11 @@ typedef struct {
|
||||
|
||||
// Describes a single font
|
||||
typedef struct {
|
||||
const char* name; // Font name
|
||||
const uint8_t height; // height, in pages (8 pixels), of the font's characters
|
||||
const uint8_t startChar; // the first character in the font (e.g. in charInfo and data)
|
||||
const uint8_t endChar; // the last character in the font
|
||||
const uint8_t spacePixels; // number of pixels that a space character takes up
|
||||
const FONT_CHAR_INFO* charInfo; // pointer to array of char information
|
||||
const uint8_t* data; // pointer to generated array of character visual representation
|
||||
|
||||
} FONT_INFO;
|
||||
+1
@@ -1163,6 +1163,7 @@ const FONT_CHAR_INFO funclimbingDemo_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for fun climbing (Demo) 18pt */
|
||||
const FONT_INFO funclimbingDemo_18ptFontInfo = {
|
||||
"Fun Climbing",
|
||||
18, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -931,6 +931,7 @@ const FONT_CHAR_INFO graph35pix_12ptDescriptors[] = {
|
||||
|
||||
/* Font information for Graph 35+ pix 12pt */
|
||||
const FONT_INFO graph35pix_12ptFontInfo = {
|
||||
"Graph 35pix",
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -1163,6 +1163,7 @@ const FONT_CHAR_INFO karmaFuture_14ptDescriptors[] = {
|
||||
|
||||
/* Font information for Karma Future 14pt */
|
||||
const FONT_INFO karmaFuture_14ptFontInfo = {
|
||||
"Karma Future",
|
||||
18, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -932,6 +932,7 @@ const FONT_CHAR_INFO modeNine_15ptDescriptors[] = {
|
||||
|
||||
/* Font information for ModeNine 15pt */
|
||||
const FONT_INFO modeNine_15ptFontInfo = {
|
||||
"Mode Nine",
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -1105,6 +1105,7 @@ const FONT_CHAR_INFO pixelFlag_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for {PixelFlag} 18pt */
|
||||
const FONT_INFO pixelFlag_18ptFontInfo = {
|
||||
"Pixel Flag",
|
||||
17, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -1048,6 +1048,7 @@ const FONT_CHAR_INFO redHatMono_16ptDescriptors[] = {
|
||||
|
||||
/* Font information for Red Hat Mono 16pt */
|
||||
const FONT_INFO redHatMono_16ptFontInfo = {
|
||||
"RedHat Mono",
|
||||
16, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+1
@@ -1047,6 +1047,7 @@ const FONT_CHAR_INFO zector_18ptDescriptors[] = {
|
||||
|
||||
/* Font information for Zector 18pt */
|
||||
const FONT_INFO zector_18ptFontInfo = {
|
||||
"Zector",
|
||||
16, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
+5
-52
@@ -15,9 +15,6 @@
|
||||
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
||||
#define CONFIG_FILE_BACKUP_DIR CONFIG_FILE_DIRECTORY_PATH "/backups"
|
||||
#define CONFIG_FILE_BACKUP_BASE_PATH CONFIG_FILE_BACKUP_DIR "/totp.conf"
|
||||
#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
|
||||
#define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig"
|
||||
#define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf"
|
||||
|
||||
struct ConfigFileContext {
|
||||
/**
|
||||
@@ -120,26 +117,6 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
totp_close_config_file(fff_data_file);
|
||||
return false;
|
||||
}
|
||||
} else if(storage_common_stat(storage, CONFIG_FILE_PATH_PREVIOUS, NULL) == FSE_OK) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Old config file %s found", CONFIG_FILE_PATH_PREVIOUS);
|
||||
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
||||
FURI_LOG_D(
|
||||
LOGGING_TAG,
|
||||
"Directory %s doesn't exist. Will create new.",
|
||||
CONFIG_FILE_DIRECTORY_PATH);
|
||||
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
||||
totp_close_config_file(fff_data_file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(storage_common_rename(storage, CONFIG_FILE_PATH_PREVIOUS, CONFIG_FILE_PATH) != FSE_OK) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error moving config to %s", CONFIG_FILE_PATH);
|
||||
totp_close_config_file(fff_data_file);
|
||||
return false;
|
||||
}
|
||||
FURI_LOG_I(LOGGING_TAG, "Applied config file path migration");
|
||||
return totp_open_config_file(storage, file);
|
||||
} else {
|
||||
FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH);
|
||||
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
||||
@@ -177,9 +154,8 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1);
|
||||
|
||||
// Default Font = 0
|
||||
tmp_uint32 = 0;
|
||||
flipper_format_write_uint32(fff_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1);
|
||||
flipper_format_write_uint32(fff_data_file, TOTP_CONFIG_KEY_FONT, &tmp_uint32, 1);
|
||||
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
totp_close_config_file(fff_data_file);
|
||||
@@ -263,24 +239,6 @@ bool totp_config_file_update_automation_method(const PluginState* plugin_state)
|
||||
return update_result;
|
||||
}
|
||||
|
||||
bool totp_config_file_update_selected_font(const PluginState* plugin_state) {
|
||||
FlipperFormat* file = plugin_state->config_file_context->config_file;
|
||||
flipper_format_rewind(file);
|
||||
bool update_result = false;
|
||||
|
||||
do {
|
||||
uint32_t tmp_uint32 = plugin_state->selected_font;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = true;
|
||||
} while(false);
|
||||
|
||||
return update_result;
|
||||
}
|
||||
|
||||
bool totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
FlipperFormat* file = plugin_state->config_file_context->config_file;
|
||||
flipper_format_rewind(file);
|
||||
@@ -302,9 +260,8 @@ bool totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_uint32 = plugin_state->selected_font;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = plugin_state->active_font_index;
|
||||
if(!flipper_format_insert_or_update_uint32(file, TOTP_CONFIG_KEY_FONT, &tmp_uint32, 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -456,15 +413,11 @@ bool totp_config_file_load(PluginState* const plugin_state) {
|
||||
|
||||
plugin_state->automation_method = tmp_uint32;
|
||||
|
||||
// Load selected font
|
||||
flipper_format_rewind(fff_data_file);
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, &tmp_uint32, 1)) {
|
||||
if(!flipper_format_read_uint32(fff_data_file, TOTP_CONFIG_KEY_FONT, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = 0;
|
||||
}
|
||||
|
||||
plugin_state->selected_font = tmp_uint32;
|
||||
plugin_state->active_font_index = tmp_uint32;
|
||||
|
||||
plugin_state->config_file_context = malloc(sizeof(ConfigFileContext));
|
||||
furi_check(plugin_state->config_file_context != NULL);
|
||||
|
||||
@@ -44,13 +44,6 @@ bool totp_config_file_update_notification_method(const PluginState* plugin_state
|
||||
*/
|
||||
bool totp_config_file_update_automation_method(const PluginState* plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Updates selected font in an application config file
|
||||
* @param plugin_state application state
|
||||
* @return Config file update result
|
||||
*/
|
||||
bool totp_config_file_update_selected_font(const PluginState* plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Updates application user settings
|
||||
* @param plugin_state application state
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator")
|
||||
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
||||
#define CONFIG_FILE_ACTUAL_VERSION (5)
|
||||
#define CONFIG_FILE_ACTUAL_VERSION (6)
|
||||
|
||||
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
||||
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
||||
@@ -18,4 +18,4 @@
|
||||
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
||||
#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
|
||||
#define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
|
||||
#define TOTP_CONFIG_KEY_SELECTED_FONT "SelectedFont"
|
||||
#define TOTP_CONFIG_KEY_FONT "Font"
|
||||
|
||||
@@ -58,11 +58,12 @@ bool totp_config_migrate_to_latest(
|
||||
|
||||
flipper_format_rewind(fff_backup_data_file);
|
||||
|
||||
// Font
|
||||
|
||||
if(flipper_format_read_string(
|
||||
fff_backup_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_SELECTED_FONT, temp_str);
|
||||
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_FONT, temp_str)) {
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_FONT, temp_str);
|
||||
} else {
|
||||
uint32_t default_font_index = 0;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_FONT, &default_font_index, 1);
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_backup_data_file);
|
||||
@@ -84,13 +85,13 @@ bool totp_config_migrate_to_latest(
|
||||
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str);
|
||||
|
||||
if(current_version < 5) {
|
||||
uint32_t algo_as_uint32t = SHA1;
|
||||
if(furi_string_cmpi_str(temp_str, TOTP_TOKEN_ALGO_SHA256_NAME) == 0) {
|
||||
algo_as_uint32t = SHA256;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOTP_TOKEN_ALGO_SHA512_NAME) == 0) {
|
||||
algo_as_uint32t = SHA512;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOTP_TOKEN_ALGO_STEAM_NAME) == 0) {
|
||||
algo_as_uint32t = STEAM;
|
||||
uint32_t algo_as_uint32t = TokenHashAlgoDefault;
|
||||
if(furi_string_cmpi_str(temp_str, TOKEN_HASH_ALGO_SHA256_NAME) == 0) {
|
||||
algo_as_uint32t = TokenHashAlgoSha256;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOKEN_HASH_ALGO_SHA512_NAME) == 0) {
|
||||
algo_as_uint32t = TokenHashAlgoSha512;
|
||||
} else if(furi_string_cmpi_str(temp_str, TOKEN_HASH_ALGO_STEAM_NAME) == 0) {
|
||||
algo_as_uint32t = TokenHashAlgoSteam;
|
||||
}
|
||||
|
||||
flipper_format_write_uint32(
|
||||
@@ -104,10 +105,10 @@ bool totp_config_migrate_to_latest(
|
||||
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str);
|
||||
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str);
|
||||
} else {
|
||||
const uint32_t default_algo = SHA1;
|
||||
const uint32_t default_algo = TokenHashAlgoDefault;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, &default_algo, 1);
|
||||
const uint32_t default_digits = TotpSixDigitsCount;
|
||||
const uint32_t default_digits = TokenDigitsCountSix;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1);
|
||||
}
|
||||
@@ -118,7 +119,7 @@ bool totp_config_migrate_to_latest(
|
||||
flipper_format_write_string(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, temp_str);
|
||||
} else {
|
||||
const uint32_t default_duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
const uint32_t default_duration = TokenDurationDefault;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &default_duration, 1);
|
||||
}
|
||||
|
||||
@@ -496,19 +496,19 @@ bool totp_token_info_iterator_go_to(TokenInfoIteratorContext* context, size_t to
|
||||
if(!flipper_format_read_uint32(
|
||||
context->config_file, TOTP_CONFIG_KEY_TOKEN_ALGO, &temp_data32, 1) ||
|
||||
!token_info_set_algo_from_int(tokenInfo, temp_data32)) {
|
||||
tokenInfo->algo = SHA1;
|
||||
tokenInfo->algo = TokenHashAlgoDefault;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
context->config_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &temp_data32, 1) ||
|
||||
!token_info_set_digits_from_int(tokenInfo, temp_data32)) {
|
||||
tokenInfo->digits = TotpSixDigitsCount;
|
||||
tokenInfo->digits = TokenDigitsCountSix;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_uint32(
|
||||
context->config_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &temp_data32, 1) ||
|
||||
!token_info_set_duration_from_int(tokenInfo, temp_data32)) {
|
||||
tokenInfo->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
tokenInfo->duration = TokenDurationDefault;
|
||||
}
|
||||
|
||||
if(flipper_format_read_uint32(
|
||||
|
||||
+3
-6
@@ -90,11 +90,8 @@ CryptoSeedIVResult
|
||||
} else {
|
||||
max_i = uid_size;
|
||||
}
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
const uint8_t* uid = furi_hal_version_uid_default();
|
||||
#else
|
||||
const uint8_t* uid = furi_hal_version_uid();
|
||||
#endif
|
||||
|
||||
const uint8_t* uid = (const uint8_t*)UID64_BASE; //-V566
|
||||
for(uint8_t i = 0; i < max_i; i++) {
|
||||
plugin_state->iv[i] = plugin_state->iv[i] ^ uid[i];
|
||||
}
|
||||
@@ -137,4 +134,4 @@ bool totp_crypto_verify_key(const PluginState* plugin_state) {
|
||||
free(decrypted_key);
|
||||
|
||||
return key_valid;
|
||||
}
|
||||
}
|
||||
@@ -63,4 +63,4 @@ void idle_timeout_free(IdleTimeoutContext* context) {
|
||||
furi_timer_stop(context->timer);
|
||||
furi_timer_free(context->timer);
|
||||
free(context);
|
||||
}
|
||||
}
|
||||
@@ -41,4 +41,4 @@ void idle_timeout_report_activity(IdleTimeoutContext* context);
|
||||
* @brief Disposes IDLE timeout and releases all the resources
|
||||
* @param context IDLE timeout context
|
||||
*/
|
||||
void idle_timeout_free(IdleTimeoutContext* context);
|
||||
void idle_timeout_free(IdleTimeoutContext* context);
|
||||
+1
-2
@@ -115,7 +115,6 @@ static bool on_user_idle(void* context) {
|
||||
}
|
||||
|
||||
static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->selected_font = 0;
|
||||
plugin_state->gui = furi_record_open(RECORD_GUI);
|
||||
plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
||||
plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
|
||||
@@ -207,7 +206,7 @@ int32_t totp_app() {
|
||||
PluginEvent event;
|
||||
bool processing = true;
|
||||
while(processing) {
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever);
|
||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||
|
||||
if(furi_mutex_acquire(plugin_state->mutex, FuriWaitForever) == FuriStatusOk) {
|
||||
if(event_status == FuriStatusOk) {
|
||||
|
||||
+5
-5
@@ -84,11 +84,6 @@ typedef struct {
|
||||
*/
|
||||
NotificationMethod notification_method;
|
||||
|
||||
/**
|
||||
* @brief Numbers Font
|
||||
*/
|
||||
uint8_t selected_font;
|
||||
|
||||
/**
|
||||
* @brief Main rendering loop mutex
|
||||
*/
|
||||
@@ -110,4 +105,9 @@ typedef struct {
|
||||
* @brief IDLE timeout context
|
||||
*/
|
||||
IdleTimeoutContext* idle_timeout_context;
|
||||
|
||||
/**
|
||||
* @brief Font index to be used to draw TOTP token
|
||||
*/
|
||||
uint8_t active_font_index;
|
||||
} PluginState;
|
||||
|
||||
+39
-36
@@ -69,13 +69,13 @@ bool token_info_set_secret(
|
||||
bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
|
||||
switch(digits) {
|
||||
case 5:
|
||||
token_info->digits = TotpFiveDigitsCount;
|
||||
token_info->digits = TokenDigitsCountFive;
|
||||
return true;
|
||||
case 6:
|
||||
token_info->digits = TotpSixDigitsCount;
|
||||
token_info->digits = TokenDigitsCountSix;
|
||||
return true;
|
||||
case 8:
|
||||
token_info->digits = TotpEightDigitsCount;
|
||||
token_info->digits = TokenDigitsCountEight;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
@@ -85,32 +85,35 @@ bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
|
||||
}
|
||||
|
||||
bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration) {
|
||||
if(duration >= 15) {
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
if(duration >= TokenDurationMin && duration <= TokenDurationMax) { //-V560
|
||||
token_info->duration = duration;
|
||||
return true;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) {
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA1_NAME) == 0) {
|
||||
token_info->algo = SHA1;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_SHA1_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSha1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA256_NAME) == 0) {
|
||||
token_info->algo = SHA256;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_SHA256_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSha256;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_SHA512_NAME) == 0) {
|
||||
token_info->algo = SHA512;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_SHA512_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSha512;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_STEAM_NAME) == 0) {
|
||||
token_info->algo = STEAM;
|
||||
if(furi_string_cmpi_str(str, TOKEN_HASH_ALGO_STEAM_NAME) == 0) {
|
||||
token_info->algo = TokenHashAlgoSteam;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -119,17 +122,17 @@ bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str)
|
||||
|
||||
bool token_info_set_algo_from_int(TokenInfo* token_info, uint8_t algo_code) {
|
||||
switch(algo_code) {
|
||||
case SHA1:
|
||||
token_info->algo = SHA1;
|
||||
case TokenHashAlgoSha1:
|
||||
token_info->algo = TokenHashAlgoSha1;
|
||||
break;
|
||||
case SHA256:
|
||||
token_info->algo = SHA256;
|
||||
case TokenHashAlgoSha256:
|
||||
token_info->algo = TokenHashAlgoSha256;
|
||||
break;
|
||||
case SHA512:
|
||||
token_info->algo = SHA512;
|
||||
case TokenHashAlgoSha512:
|
||||
token_info->algo = TokenHashAlgoSha512;
|
||||
break;
|
||||
case STEAM:
|
||||
token_info->algo = STEAM;
|
||||
case TokenHashAlgoSteam:
|
||||
token_info->algo = TokenHashAlgoSteam;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@@ -138,16 +141,16 @@ bool token_info_set_algo_from_int(TokenInfo* token_info, uint8_t algo_code) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
const char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
switch(token_info->algo) {
|
||||
case SHA1:
|
||||
return TOTP_TOKEN_ALGO_SHA1_NAME;
|
||||
case SHA256:
|
||||
return TOTP_TOKEN_ALGO_SHA256_NAME;
|
||||
case SHA512:
|
||||
return TOTP_TOKEN_ALGO_SHA512_NAME;
|
||||
case STEAM:
|
||||
return TOTP_TOKEN_ALGO_STEAM_NAME;
|
||||
case TokenHashAlgoSha1:
|
||||
return TOKEN_HASH_ALGO_SHA1_NAME;
|
||||
case TokenHashAlgoSha256:
|
||||
return TOKEN_HASH_ALGO_SHA256_NAME;
|
||||
case TokenHashAlgoSha512:
|
||||
return TOKEN_HASH_ALGO_SHA512_NAME;
|
||||
case TokenHashAlgoSteam:
|
||||
return TOKEN_HASH_ALGO_STEAM_NAME;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -156,22 +159,22 @@ char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
}
|
||||
|
||||
bool token_info_set_automation_feature_from_str(TokenInfo* token_info, const FuriString* str) {
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME) == 0) {
|
||||
token_info->automation_features |= TokenAutomationFeatureEnterAtTheEnd;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME) == 0) {
|
||||
token_info->automation_features |= TokenAutomationFeatureTabAtTheEnd;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME) == 0) {
|
||||
token_info->automation_features |= TokenAutomationFeatureTypeSlower;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME) == 0) {
|
||||
if(furi_string_cmpi_str(str, TOKEN_AUTOMATION_FEATURE_NONE_NAME) == 0) {
|
||||
token_info->automation_features = TokenAutomationFeatureNone;
|
||||
return true;
|
||||
}
|
||||
@@ -195,9 +198,9 @@ TokenInfo* token_info_clone(const TokenInfo* src) {
|
||||
|
||||
void token_info_set_defaults(TokenInfo* token_info) {
|
||||
furi_check(token_info != NULL);
|
||||
token_info->algo = SHA1;
|
||||
token_info->digits = TotpSixDigitsCount;
|
||||
token_info->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
token_info->algo = TokenHashAlgoDefault;
|
||||
token_info->digits = TokenDigitsCountDefault;
|
||||
token_info->duration = TokenDurationDefault;
|
||||
token_info->automation_features = TokenAutomationFeatureNone;
|
||||
furi_string_reset(token_info->name);
|
||||
}
|
||||
+53
-24
@@ -4,26 +4,20 @@
|
||||
#include <stdbool.h>
|
||||
#include <furi/core/string.h>
|
||||
|
||||
#define TOTP_TOKEN_DURATION_DEFAULT (30)
|
||||
|
||||
#define TOTP_TOKEN_ALGO_SHA1_NAME "sha1"
|
||||
#define TOTP_TOKEN_ALGO_STEAM_NAME "steam"
|
||||
#define TOTP_TOKEN_ALGO_SHA256_NAME "sha256"
|
||||
#define TOTP_TOKEN_ALGO_SHA512_NAME "sha512"
|
||||
#define TOTP_TOKEN_MAX_LENGTH (255)
|
||||
|
||||
#define TOKEN_HASH_ALGO_SHA1_NAME "sha1"
|
||||
#define TOKEN_HASH_ALGO_STEAM_NAME "steam"
|
||||
#define TOKEN_HASH_ALGO_SHA256_NAME "sha256"
|
||||
#define TOKEN_HASH_ALGO_SHA512_NAME "sha512"
|
||||
#define PLAIN_TOKEN_ENCODING_BASE32_NAME "base32"
|
||||
#define PLAIN_TOKEN_ENCODING_BASE64_NAME "base64"
|
||||
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME "none"
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME "enter"
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME "tab"
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME "slower"
|
||||
|
||||
#define TOTP_TOKEN_DIGITS_MAX_COUNT (8)
|
||||
#define TOKEN_AUTOMATION_FEATURE_NONE_NAME "none"
|
||||
#define TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME "enter"
|
||||
#define TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME "tab"
|
||||
#define TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER_NAME "slower"
|
||||
|
||||
typedef uint8_t TokenHashAlgo;
|
||||
typedef uint8_t TokenDigitsCount;
|
||||
typedef uint8_t TokenDuration;
|
||||
typedef uint8_t TokenAutomationFeature;
|
||||
typedef uint8_t PlainTokenSecretEncoding;
|
||||
|
||||
@@ -34,22 +28,27 @@ enum TokenHashAlgos {
|
||||
/**
|
||||
* @brief SHA1 hashing algorithm
|
||||
*/
|
||||
SHA1 = 0,
|
||||
TokenHashAlgoSha1 = 0,
|
||||
|
||||
/**
|
||||
* @brief SHA256 hashing algorithm
|
||||
*/
|
||||
SHA256 = 1,
|
||||
TokenHashAlgoSha256 = 1,
|
||||
|
||||
/**
|
||||
* @brief SHA512 hashing algorithm
|
||||
*/
|
||||
SHA512 = 2,
|
||||
TokenHashAlgoSha512 = 2,
|
||||
|
||||
/**
|
||||
* @brief Algorithm used by Steam (Valve)
|
||||
*/
|
||||
STEAM = 3
|
||||
TokenHashAlgoSteam = 3,
|
||||
|
||||
/**
|
||||
* @brief Default token hashing algorithm
|
||||
*/
|
||||
TokenHashAlgoDefault = TokenHashAlgoSha1
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -59,17 +58,47 @@ enum TokenDigitsCounts {
|
||||
/**
|
||||
* @brief 5 digits
|
||||
*/
|
||||
TotpFiveDigitsCount = 5,
|
||||
TokenDigitsCountFive = 5,
|
||||
|
||||
/**
|
||||
* @brief 6 digits
|
||||
*/
|
||||
TotpSixDigitsCount = 6,
|
||||
TokenDigitsCountSix = 6,
|
||||
|
||||
/**
|
||||
* @brief 8 digits
|
||||
*/
|
||||
TotpEightDigitsCount = 8
|
||||
TokenDigitsCountEight = 8,
|
||||
|
||||
/**
|
||||
* @brief Default digits count
|
||||
*/
|
||||
TokenDigitsCountDefault = TokenDigitsCountSix,
|
||||
|
||||
/**
|
||||
* @brief Maximum digits count
|
||||
*/
|
||||
TokenDigitsCountMax = TokenDigitsCountEight
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Token durations
|
||||
*/
|
||||
enum TokenDurations {
|
||||
/**
|
||||
* @brief Default token duration
|
||||
*/
|
||||
TokenDurationDefault = 30,
|
||||
|
||||
/**
|
||||
* @brief Minimum token duration
|
||||
*/
|
||||
TokenDurationMin = 15,
|
||||
|
||||
/**
|
||||
* @brief Maximum token duration
|
||||
*/
|
||||
TokenDurationMax = UINT8_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -145,7 +174,7 @@ typedef struct {
|
||||
/**
|
||||
* @brief Desired TOTP token duration in seconds
|
||||
*/
|
||||
uint8_t duration;
|
||||
TokenDuration duration;
|
||||
|
||||
/**
|
||||
* @brief Token input automation features
|
||||
@@ -218,7 +247,7 @@ bool token_info_set_algo_from_int(TokenInfo* token_info, uint8_t algo_code);
|
||||
* @param token_info instance which token hahsing algorithm name should be returned
|
||||
* @return token hashing algorithm name as C-string
|
||||
*/
|
||||
char* token_info_get_algo_as_cstr(const TokenInfo* token_info);
|
||||
const char* token_info_get_algo_as_cstr(const TokenInfo* token_info);
|
||||
|
||||
/**
|
||||
* @brief Sets token automation feature from \c str value
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "canvas_extensions.h"
|
||||
|
||||
void canvas_draw_str_ex(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
const char* text,
|
||||
size_t text_length,
|
||||
const FONT_INFO* const font) {
|
||||
const char* p_ch = text;
|
||||
char ch;
|
||||
size_t i = 0;
|
||||
uint8_t offset_x = x;
|
||||
uint8_t char_width = font->charInfo[0].width;
|
||||
uint8_t offset_x_inc = char_width + font->spacePixels;
|
||||
while(i < text_length && (ch = *p_ch) != 0) {
|
||||
if(ch >= font->startChar && ch <= font->endChar) {
|
||||
uint8_t char_index = ch - font->startChar;
|
||||
canvas_draw_xbm(
|
||||
canvas,
|
||||
offset_x,
|
||||
y,
|
||||
char_width,
|
||||
font->height,
|
||||
&font->data[font->charInfo[char_index].offset]);
|
||||
}
|
||||
|
||||
offset_x += offset_x_inc;
|
||||
|
||||
p_ch++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <gui/gui.h>
|
||||
#include <font_info.h>
|
||||
|
||||
void canvas_draw_str_ex(
|
||||
Canvas* canvas,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
const char* text,
|
||||
size_t text_length,
|
||||
const FONT_INFO* const font);
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../features_config.h"
|
||||
#include "font_info.h"
|
||||
|
||||
#include "mode_nine/mode_nine.h"
|
||||
#include "redhat_mono/redhat_mono.h"
|
||||
#include "bedstead/bedstead.h"
|
||||
#include "zector/zector.h"
|
||||
#include "712serif/712serif.h"
|
||||
#include "graph35pix/graph35pix.h"
|
||||
#include "karma_future/karma_future.h"
|
||||
#include "funclimbing/funclimbing.h"
|
||||
#include "dpcomic/dpcomic.h"
|
||||
#include "pixelflag/pixelflag.h"
|
||||
@@ -1,81 +1,52 @@
|
||||
#include "totp_input_text.h"
|
||||
#include <gui/view_i.h>
|
||||
|
||||
void view_draw(View* view, Canvas* canvas) {
|
||||
furi_assert(view);
|
||||
if(view->draw_callback) {
|
||||
void* data = view_get_model(view);
|
||||
view->draw_callback(canvas, data);
|
||||
view_unlock_model(view);
|
||||
}
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
|
||||
typedef struct {
|
||||
InputTextResult* result;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
} InputTextContext;
|
||||
|
||||
static void commit_text_input_callback(void* ctx) {
|
||||
InputTextContext* context = ctx;
|
||||
context->result->user_input_length = strnlen(context->result->user_input, INPUT_BUFFER_SIZE);
|
||||
context->result->success = true;
|
||||
view_dispatcher_stop(context->view_dispatcher);
|
||||
}
|
||||
|
||||
bool view_input(View* view, InputEvent* event) {
|
||||
furi_assert(view);
|
||||
if(view->input_callback) {
|
||||
return view->input_callback(event, view->context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
static bool back_event_callback(void* ctx) {
|
||||
InputTextContext* context = ctx;
|
||||
context->result->success = false;
|
||||
view_dispatcher_stop(context->view_dispatcher);
|
||||
return false;
|
||||
}
|
||||
|
||||
void view_unlock_model(View* view) {
|
||||
furi_assert(view);
|
||||
if(view->model_type == ViewModelTypeLocking) {
|
||||
ViewModelLocking* model = (ViewModelLocking*)(view->model);
|
||||
furi_check(furi_mutex_release(model->mutex) == FuriStatusOk);
|
||||
}
|
||||
}
|
||||
|
||||
static void commit_text_input_callback(void* context) {
|
||||
InputTextSceneState* text_input_state = (InputTextSceneState*)context;
|
||||
if(text_input_state->callback != NULL) {
|
||||
InputTextSceneCallbackResult* result = malloc(sizeof(InputTextSceneCallbackResult));
|
||||
furi_check(result != NULL);
|
||||
result->user_input_length =
|
||||
strnlen(text_input_state->text_input_buffer, INPUT_BUFFER_SIZE);
|
||||
result->user_input = malloc(result->user_input_length + 1);
|
||||
furi_check(result->user_input != NULL);
|
||||
result->callback_data = text_input_state->callback_data;
|
||||
strlcpy(
|
||||
result->user_input,
|
||||
text_input_state->text_input_buffer,
|
||||
result->user_input_length + 1);
|
||||
text_input_state->callback(result);
|
||||
}
|
||||
}
|
||||
|
||||
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context) {
|
||||
InputTextSceneState* text_input_state = malloc(sizeof(InputTextSceneState));
|
||||
furi_check(text_input_state != NULL);
|
||||
text_input_state->text_input = text_input_alloc();
|
||||
text_input_state->text_input_view = text_input_get_view(text_input_state->text_input);
|
||||
text_input_state->callback = context->callback;
|
||||
text_input_state->callback_data = context->callback_data;
|
||||
text_input_set_header_text(text_input_state->text_input, context->header_text);
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result) {
|
||||
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
|
||||
TextInput* text_input = text_input_alloc();
|
||||
InputTextContext context = {.result = result, .view_dispatcher = view_dispatcher};
|
||||
text_input_set_header_text(text_input, header_text);
|
||||
text_input_set_result_callback(
|
||||
text_input_state->text_input,
|
||||
text_input,
|
||||
commit_text_input_callback,
|
||||
text_input_state,
|
||||
&text_input_state->text_input_buffer[0],
|
||||
&context,
|
||||
result->user_input,
|
||||
INPUT_BUFFER_SIZE,
|
||||
true);
|
||||
return text_input_state;
|
||||
}
|
||||
|
||||
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state) {
|
||||
view_draw(text_input_state->text_input_view, canvas);
|
||||
}
|
||||
view_dispatcher_enable_queue(view_dispatcher);
|
||||
view_dispatcher_add_view(view_dispatcher, 0, text_input_get_view(text_input));
|
||||
|
||||
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state) {
|
||||
if(event->type == EventTypeKey) {
|
||||
view_input(text_input_state->text_input_view, &event->input);
|
||||
}
|
||||
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
return true;
|
||||
}
|
||||
view_dispatcher_set_navigation_event_callback(view_dispatcher, &back_event_callback);
|
||||
view_dispatcher_set_event_callback_context(view_dispatcher, &context);
|
||||
view_dispatcher_switch_to_view(view_dispatcher, 0);
|
||||
|
||||
void totp_input_text_free(InputTextSceneState* state) {
|
||||
text_input_free(state->text_input);
|
||||
free(state);
|
||||
view_dispatcher_run(view_dispatcher);
|
||||
|
||||
view_dispatcher_remove_view(view_dispatcher, 0);
|
||||
view_dispatcher_free(view_dispatcher);
|
||||
text_input_free(text_input);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include "../../../types/plugin_state.h"
|
||||
#include "../../../types/plugin_event.h"
|
||||
|
||||
#define INPUT_BUFFER_SIZE (255)
|
||||
|
||||
typedef struct {
|
||||
char* user_input;
|
||||
char user_input[INPUT_BUFFER_SIZE];
|
||||
size_t user_input_length;
|
||||
void* callback_data;
|
||||
} InputTextSceneCallbackResult;
|
||||
bool success;
|
||||
} InputTextResult;
|
||||
|
||||
typedef void (*InputTextSceneCallback)(InputTextSceneCallbackResult* result);
|
||||
|
||||
typedef struct {
|
||||
InputTextSceneCallback callback;
|
||||
char* header_text;
|
||||
void* callback_data;
|
||||
} InputTextSceneContext;
|
||||
|
||||
typedef struct {
|
||||
TextInput* text_input;
|
||||
View* text_input_view;
|
||||
char text_input_buffer[INPUT_BUFFER_SIZE];
|
||||
InputTextSceneCallback callback;
|
||||
void* callback_data;
|
||||
} InputTextSceneState;
|
||||
|
||||
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context);
|
||||
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state);
|
||||
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state);
|
||||
void totp_input_text_free(InputTextSceneState* state);
|
||||
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result);
|
||||
|
||||
+49
-90
@@ -13,9 +13,9 @@
|
||||
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
|
||||
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
|
||||
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
|
||||
TotpFiveDigitsCount,
|
||||
TotpSixDigitsCount,
|
||||
TotpEightDigitsCount};
|
||||
TokenDigitsCountFive,
|
||||
TokenDigitsCountSix,
|
||||
TokenDigitsCountEight};
|
||||
|
||||
typedef enum {
|
||||
TokenNameTextBox,
|
||||
@@ -33,10 +33,6 @@ typedef struct {
|
||||
size_t token_secret_length;
|
||||
bool saved;
|
||||
Control selected_control;
|
||||
InputTextSceneContext* token_name_input_context;
|
||||
InputTextSceneContext* token_secret_input_context;
|
||||
InputTextSceneState* input_state;
|
||||
bool text_input_mode;
|
||||
int16_t screen_y_offset;
|
||||
TokenHashAlgo algo;
|
||||
uint8_t digits_count_index;
|
||||
@@ -51,24 +47,6 @@ struct TotpAddContext {
|
||||
|
||||
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
|
||||
|
||||
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
|
||||
SceneState* scene_state = result->callback_data;
|
||||
free(scene_state->token_name);
|
||||
scene_state->token_name = result->user_input;
|
||||
scene_state->token_name_length = result->user_input_length;
|
||||
scene_state->text_input_mode = false;
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result) {
|
||||
SceneState* scene_state = result->callback_data;
|
||||
free(scene_state->token_secret);
|
||||
scene_state->token_secret = result->user_input;
|
||||
scene_state->token_secret_length = result->user_input_length;
|
||||
scene_state->text_input_mode = false;
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void update_duration_text(SceneState* scene_state) {
|
||||
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
|
||||
}
|
||||
@@ -95,6 +73,26 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
|
||||
return TotpIteratorUpdateTokenResultSuccess;
|
||||
}
|
||||
|
||||
static void ask_user_input(
|
||||
const PluginState* plugin_state,
|
||||
const char* header,
|
||||
char** user_input,
|
||||
size_t* user_input_length) {
|
||||
InputTextResult input_result;
|
||||
if(*user_input != NULL) {
|
||||
strlcpy(input_result.user_input, *user_input, INPUT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
totp_input_text(plugin_state->gui, header, &input_result);
|
||||
if(input_result.success) {
|
||||
if(*user_input != NULL) {
|
||||
free(*user_input);
|
||||
}
|
||||
*user_input = strdup(input_result.user_input);
|
||||
*user_input_length = input_result.user_input_length;
|
||||
}
|
||||
}
|
||||
|
||||
void totp_scene_add_new_token_activate(PluginState* plugin_state) {
|
||||
SceneState* scene_state = malloc(sizeof(SceneState));
|
||||
furi_check(scene_state != NULL);
|
||||
@@ -104,34 +102,17 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state) {
|
||||
scene_state->token_secret = "Secret";
|
||||
scene_state->token_secret_length = strlen(scene_state->token_secret);
|
||||
|
||||
scene_state->token_name_input_context = malloc(sizeof(InputTextSceneContext));
|
||||
furi_check(scene_state->token_name_input_context != NULL);
|
||||
scene_state->token_name_input_context->header_text = "Enter token name";
|
||||
scene_state->token_name_input_context->callback_data = scene_state;
|
||||
scene_state->token_name_input_context->callback = on_token_name_user_comitted;
|
||||
|
||||
scene_state->token_secret_input_context = malloc(sizeof(InputTextSceneContext));
|
||||
furi_check(scene_state->token_secret_input_context != NULL);
|
||||
scene_state->token_secret_input_context->header_text = "Enter token secret";
|
||||
scene_state->token_secret_input_context->callback_data = scene_state;
|
||||
scene_state->token_secret_input_context->callback = on_token_secret_user_comitted;
|
||||
|
||||
scene_state->screen_y_offset = 0;
|
||||
|
||||
scene_state->digits_count_index = 1;
|
||||
|
||||
scene_state->input_state = NULL;
|
||||
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
scene_state->duration = TokenDurationDefault;
|
||||
scene_state->duration_text = furi_string_alloc();
|
||||
update_duration_text(scene_state);
|
||||
}
|
||||
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state) {
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
if(scene_state->text_input_mode) {
|
||||
totp_input_text_render(canvas, scene_state->input_state);
|
||||
return;
|
||||
}
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state) {
|
||||
const SceneState* scene_state = plugin_state->current_scene_state;
|
||||
|
||||
ui_control_text_box_render(
|
||||
canvas,
|
||||
@@ -195,31 +176,15 @@ void update_screen_y_offset(SceneState* scene_state) {
|
||||
}
|
||||
}
|
||||
|
||||
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state) {
|
||||
bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state) {
|
||||
if(event->type != EventTypeKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
|
||||
if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) {
|
||||
if(scene_state->text_input_mode) {
|
||||
scene_state->text_input_mode = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(scene_state->text_input_mode) {
|
||||
if(event->input.type == InputTypeShort && event->input.key == InputKeyBack) {
|
||||
PluginEvent long_back_cb_evt = {
|
||||
.type = event->type, .input.key = InputKeyBack, .input.type = InputTypeLong};
|
||||
return totp_input_text_handle_event(&long_back_cb_evt, scene_state->input_state);
|
||||
}
|
||||
|
||||
return totp_input_text_handle_event(event, scene_state->input_state);
|
||||
}
|
||||
|
||||
if(event->input.type == InputTypePress) {
|
||||
switch(event->input.key) {
|
||||
case InputKeyUp:
|
||||
@@ -243,7 +208,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
case InputKeyRight:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, 1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
&scene_state->algo,
|
||||
1,
|
||||
TokenHashAlgoSha1,
|
||||
TokenHashAlgoSteam,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, 1, 0, 2, RollOverflowBehaviorRoll);
|
||||
@@ -256,7 +225,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, -1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
&scene_state->algo,
|
||||
-1,
|
||||
TokenHashAlgoSha1,
|
||||
TokenHashAlgoSteam,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, -1, 0, 2, RollOverflowBehaviorRoll);
|
||||
@@ -277,22 +250,18 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
|
||||
switch(scene_state->selected_control) {
|
||||
case TokenNameTextBox:
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
scene_state->input_state =
|
||||
totp_input_text_activate(scene_state->token_name_input_context);
|
||||
|
||||
scene_state->text_input_mode = true;
|
||||
ask_user_input(
|
||||
plugin_state,
|
||||
"Token name",
|
||||
&scene_state->token_name,
|
||||
&scene_state->token_name_length);
|
||||
break;
|
||||
case TokenSecretTextBox:
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
scene_state->input_state =
|
||||
totp_input_text_activate(scene_state->token_secret_input_context);
|
||||
|
||||
scene_state->text_input_mode = true;
|
||||
ask_user_input(
|
||||
plugin_state,
|
||||
"Token secret",
|
||||
&scene_state->token_secret,
|
||||
&scene_state->token_secret_length);
|
||||
break;
|
||||
case TokenAlgoSelect:
|
||||
break;
|
||||
@@ -344,18 +313,8 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
|
||||
free(scene_state->token_name);
|
||||
free(scene_state->token_secret);
|
||||
|
||||
free(scene_state->token_name_input_context->header_text);
|
||||
free(scene_state->token_name_input_context);
|
||||
|
||||
free(scene_state->token_secret_input_context->header_text);
|
||||
free(scene_state->token_secret_input_context);
|
||||
|
||||
furi_string_free(scene_state->duration_text);
|
||||
|
||||
if(scene_state->input_state != NULL) {
|
||||
totp_input_text_free(scene_state->input_state);
|
||||
}
|
||||
|
||||
free(plugin_state->current_scene_state);
|
||||
plugin_state->current_scene_state = NULL;
|
||||
}
|
||||
|
||||
+4
-2
@@ -5,6 +5,8 @@
|
||||
#include "../../../types/plugin_event.h"
|
||||
|
||||
void totp_scene_add_new_token_activate(PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state);
|
||||
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state);
|
||||
bool totp_scene_add_new_token_handle_event(
|
||||
const PluginEvent* const event,
|
||||
PluginState* plugin_state);
|
||||
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <math.h>
|
||||
#include <totp_icons.h>
|
||||
#include <assets_icons.h>
|
||||
#include <available_fonts.h>
|
||||
#include "../../canvas_extensions.h"
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../scene_director.h"
|
||||
@@ -15,18 +17,20 @@
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
|
||||
char* YES_NO_LIST[] = {"NO", "YES"};
|
||||
char* ON_OFF_LIST[] = {"OFF", "ON"};
|
||||
static const char* YES_NO_LIST[] = {"NO", "YES"};
|
||||
static const char* ON_OFF_LIST[] = {"OFF", "ON"};
|
||||
static const char* FONT_TEST_STR = "0123BCD";
|
||||
static const uint8_t FONT_TEST_STR_LENGTH = 7;
|
||||
|
||||
typedef enum {
|
||||
HoursInput,
|
||||
MinutesInput,
|
||||
Sound,
|
||||
Vibro,
|
||||
FontSelector,
|
||||
BadUsb,
|
||||
FontSelect,
|
||||
SoundSwitch,
|
||||
VibroSwitch,
|
||||
BadUsbSwitch,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
BadBt,
|
||||
BadBtSwitch,
|
||||
#endif
|
||||
ConfirmButton
|
||||
} Control;
|
||||
@@ -36,13 +40,13 @@ typedef struct {
|
||||
uint8_t tz_offset_minutes;
|
||||
bool notification_sound;
|
||||
bool notification_vibro;
|
||||
uint8_t selected_font;
|
||||
bool badusb_enabled;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
bool badbt_enabled;
|
||||
#endif
|
||||
uint8_t y_offset;
|
||||
Control selected_control;
|
||||
uint8_t active_font;
|
||||
} SceneState;
|
||||
|
||||
void totp_scene_app_settings_activate(PluginState* plugin_state) {
|
||||
@@ -57,10 +61,10 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
|
||||
scene_state->notification_sound = plugin_state->notification_method & NotificationMethodSound;
|
||||
scene_state->notification_vibro = plugin_state->notification_method & NotificationMethodVibro;
|
||||
scene_state->badusb_enabled = plugin_state->automation_method & AutomationMethodBadUsb;
|
||||
scene_state->selected_font = plugin_state->selected_font;
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
scene_state->badbt_enabled = plugin_state->automation_method & AutomationMethodBadBt;
|
||||
#endif
|
||||
scene_state->active_font = plugin_state->active_font_index;
|
||||
}
|
||||
|
||||
static void two_digit_to_str(int8_t num, char* str) {
|
||||
@@ -114,75 +118,87 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
|
||||
&I_totp_arrow_bottom_10x5);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications / UI");
|
||||
canvas_draw_str_aligned(canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 0, 78 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
|
||||
const FONT_INFO* const font = available_fonts[scene_state->active_font];
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
71 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_sound],
|
||||
scene_state->selected_control == Sound);
|
||||
0,
|
||||
74 - scene_state->y_offset,
|
||||
SCREEN_WIDTH,
|
||||
font->name,
|
||||
scene_state->selected_control == FontSelect);
|
||||
|
||||
canvas_draw_str_aligned(canvas, 0, 94 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
87 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_vibro],
|
||||
scene_state->selected_control == Vibro);
|
||||
|
||||
two_digit_to_str(scene_state->selected_font, &tmp_str[0]);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 110 - scene_state->y_offset, AlignLeft, AlignTop, "UI Font:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
103 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
&tmp_str[0],
|
||||
scene_state->selected_control == FontSelector);
|
||||
uint8_t font_x_offset =
|
||||
SCREEN_WIDTH_CENTER -
|
||||
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
|
||||
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
|
||||
canvas_draw_str_ex(
|
||||
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, 123 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
|
||||
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
|
||||
canvas_draw_str_aligned(canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
138 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badusb_enabled],
|
||||
scene_state->selected_control == BadUsb);
|
||||
YES_NO_LIST[scene_state->notification_sound],
|
||||
scene_state->selected_control == SoundSwitch);
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
|
||||
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
156 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
YES_NO_LIST[scene_state->notification_vibro],
|
||||
scene_state->selected_control == VibroSwitch);
|
||||
|
||||
canvas_draw_icon(
|
||||
canvas, SCREEN_WIDTH_CENTER - 5, 187 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 192 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 0, 209 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
202 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badusb_enabled],
|
||||
scene_state->selected_control == BadUsbSwitch);
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
canvas_draw_str_aligned(canvas, 0, 227 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
|
||||
ui_control_select_render(
|
||||
canvas,
|
||||
36,
|
||||
220 - scene_state->y_offset,
|
||||
SCREEN_WIDTH - 36,
|
||||
ON_OFF_LIST[scene_state->badbt_enabled],
|
||||
scene_state->selected_control == BadBt);
|
||||
scene_state->selected_control == BadBtSwitch);
|
||||
#endif
|
||||
|
||||
ui_control_button_render(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER - 24,
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
178 - scene_state->y_offset,
|
||||
242 - scene_state->y_offset,
|
||||
#else
|
||||
165 - scene_state->y_offset,
|
||||
229 - scene_state->y_offset,
|
||||
#endif
|
||||
48,
|
||||
13,
|
||||
@@ -207,10 +223,12 @@ bool totp_scene_app_settings_handle_event(
|
||||
HoursInput,
|
||||
ConfirmButton,
|
||||
RollOverflowBehaviorStop);
|
||||
if(scene_state->selected_control > FontSelector) {
|
||||
scene_state->y_offset = 128;
|
||||
if(scene_state->selected_control > VibroSwitch) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 3;
|
||||
} else if(scene_state->selected_control > FontSelect) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 2;
|
||||
} else if(scene_state->selected_control > MinutesInput) {
|
||||
scene_state->y_offset = 64;
|
||||
scene_state->y_offset = SCREEN_HEIGHT;
|
||||
} else {
|
||||
scene_state->y_offset = 0;
|
||||
}
|
||||
@@ -222,10 +240,12 @@ bool totp_scene_app_settings_handle_event(
|
||||
HoursInput,
|
||||
ConfirmButton,
|
||||
RollOverflowBehaviorStop);
|
||||
if(scene_state->selected_control > FontSelector) {
|
||||
scene_state->y_offset = 128;
|
||||
if(scene_state->selected_control > VibroSwitch) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 3;
|
||||
} else if(scene_state->selected_control > FontSelect) {
|
||||
scene_state->y_offset = SCREEN_HEIGHT * 2;
|
||||
} else if(scene_state->selected_control > MinutesInput) {
|
||||
scene_state->y_offset = 64;
|
||||
scene_state->y_offset = SCREEN_HEIGHT;
|
||||
} else {
|
||||
scene_state->y_offset = 0;
|
||||
}
|
||||
@@ -237,22 +257,25 @@ bool totp_scene_app_settings_handle_event(
|
||||
} else if(scene_state->selected_control == MinutesInput) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->tz_offset_minutes, 15, 0, 45, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == Sound) {
|
||||
} else if(scene_state->selected_control == FontSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->active_font,
|
||||
1,
|
||||
0,
|
||||
AVAILABLE_FONTS_COUNT - 1,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == SoundSwitch) {
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == Vibro) {
|
||||
} else if(scene_state->selected_control == VibroSwitch) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsb) {
|
||||
} else if(scene_state->selected_control == BadUsbSwitch) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBt) {
|
||||
else if(scene_state->selected_control == BadBtSwitch) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
else if(scene_state->selected_control == FontSelector) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->selected_font, 1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == HoursInput) {
|
||||
@@ -261,22 +284,25 @@ bool totp_scene_app_settings_handle_event(
|
||||
} else if(scene_state->selected_control == MinutesInput) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->tz_offset_minutes, -15, 0, 45, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == Sound) {
|
||||
} else if(scene_state->selected_control == FontSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->active_font,
|
||||
-1,
|
||||
0,
|
||||
AVAILABLE_FONTS_COUNT - 1,
|
||||
RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == SoundSwitch) {
|
||||
scene_state->notification_sound = !scene_state->notification_sound;
|
||||
} else if(scene_state->selected_control == Vibro) {
|
||||
} else if(scene_state->selected_control == VibroSwitch) {
|
||||
scene_state->notification_vibro = !scene_state->notification_vibro;
|
||||
} else if(scene_state->selected_control == BadUsb) {
|
||||
} else if(scene_state->selected_control == BadUsbSwitch) {
|
||||
scene_state->badusb_enabled = !scene_state->badusb_enabled;
|
||||
}
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
else if(scene_state->selected_control == BadBt) {
|
||||
else if(scene_state->selected_control == BadBtSwitch) {
|
||||
scene_state->badbt_enabled = !scene_state->badbt_enabled;
|
||||
}
|
||||
#endif
|
||||
else if(scene_state->selected_control == FontSelector) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->selected_font, -1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
break;
|
||||
@@ -303,7 +329,8 @@ bool totp_scene_app_settings_handle_event(
|
||||
plugin_state->automation_method |= scene_state->badbt_enabled ? AutomationMethodBadBt :
|
||||
AutomationMethodNone;
|
||||
#endif
|
||||
plugin_state->selected_font = scene_state->selected_font;
|
||||
|
||||
plugin_state->active_font_index = scene_state->active_font;
|
||||
|
||||
if(!totp_config_file_update_user_settings(plugin_state)) {
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
|
||||
+19
-102
@@ -4,7 +4,9 @@
|
||||
#include <totp_icons.h>
|
||||
#include <assets_icons.h>
|
||||
#include <roll_value.h>
|
||||
#include <available_fonts.h>
|
||||
#include "totp_scene_generate_token.h"
|
||||
#include "../../canvas_extensions.h"
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../types/common.h"
|
||||
#include "../../constants.h"
|
||||
@@ -17,7 +19,6 @@
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
#include "../../fonts/active_font.h"
|
||||
|
||||
#define PROGRESS_BAR_MARGIN (3)
|
||||
#define PROGRESS_BAR_HEIGHT (4)
|
||||
@@ -27,18 +28,18 @@ typedef struct {
|
||||
uint8_t progress_bar_width;
|
||||
uint8_t code_total_length;
|
||||
uint8_t code_offset_x;
|
||||
uint8_t code_offset_x_inc;
|
||||
uint8_t code_offset_y;
|
||||
} UiPrecalculatedDimensions;
|
||||
|
||||
typedef struct {
|
||||
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
|
||||
char last_code[TokenDigitsCountMax + 1];
|
||||
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
|
||||
NotificationMessage const** notification_sequence_new_token;
|
||||
NotificationMessage const** notification_sequence_automation;
|
||||
FuriMutex* last_code_update_sync;
|
||||
TotpGenerateCodeWorkerContext* generate_code_worker_context;
|
||||
UiPrecalculatedDimensions ui_precalculated_dimensions;
|
||||
const FONT_INFO* active_font;
|
||||
} SceneState;
|
||||
|
||||
static const NotificationSequence*
|
||||
@@ -142,60 +143,14 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin
|
||||
const TokenInfoIteratorContext* iterator_context =
|
||||
totp_config_get_token_iterator_context(plugin_state);
|
||||
uint8_t code_length = totp_token_info_iterator_get_current_token(iterator_context)->digits;
|
||||
uint8_t offset_x = scene_state->ui_precalculated_dimensions.code_offset_x;
|
||||
const FONT_INFO* current_font;
|
||||
switch(plugin_state->selected_font) {
|
||||
case 0:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
case 1:
|
||||
current_font = &redHatMono_16ptFontInfo;
|
||||
break;
|
||||
case 2:
|
||||
current_font = &bedstead_17ptFontInfo;
|
||||
break;
|
||||
case 3:
|
||||
current_font = &zector_18ptFontInfo;
|
||||
break;
|
||||
case 4:
|
||||
current_font = &_712Serif_24ptFontInfo;
|
||||
break;
|
||||
case 5:
|
||||
current_font = &graph35pix_12ptFontInfo;
|
||||
break;
|
||||
case 6:
|
||||
current_font = &karmaFuture_14ptFontInfo;
|
||||
break;
|
||||
case 7:
|
||||
current_font = &funclimbingDemo_18ptFontInfo;
|
||||
break;
|
||||
case 8:
|
||||
current_font = &dPComic_18ptFontInfo;
|
||||
break;
|
||||
case 9:
|
||||
current_font = &pixelFlag_18ptFontInfo;
|
||||
break;
|
||||
default:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
}
|
||||
uint8_t char_width = current_font->charInfo[0].width;
|
||||
uint8_t offset_x_inc = scene_state->ui_precalculated_dimensions.code_offset_x_inc;
|
||||
for(uint8_t i = 0; i < code_length; i++) {
|
||||
char ch = scene_state->last_code[i];
|
||||
if(ch >= current_font->startChar && ch <= current_font->endChar) {
|
||||
uint8_t char_index = ch - current_font->startChar;
|
||||
canvas_draw_xbm(
|
||||
canvas,
|
||||
offset_x,
|
||||
scene_state->ui_precalculated_dimensions.code_offset_y,
|
||||
char_width,
|
||||
current_font->height,
|
||||
¤t_font->data[current_font->charInfo[char_index].offset]);
|
||||
}
|
||||
|
||||
offset_x += offset_x_inc;
|
||||
}
|
||||
canvas_draw_str_ex(
|
||||
canvas,
|
||||
scene_state->ui_precalculated_dimensions.code_offset_x,
|
||||
scene_state->ui_precalculated_dimensions.code_offset_y,
|
||||
scene_state->last_code,
|
||||
code_length,
|
||||
scene_state->active_font);
|
||||
}
|
||||
|
||||
static void on_new_token_code_generated(bool time_left, void* context) {
|
||||
@@ -208,53 +163,15 @@ static void on_new_token_code_generated(bool time_left, void* context) {
|
||||
|
||||
SceneState* scene_state = plugin_state->current_scene_state;
|
||||
const TokenInfo* current_token = totp_token_info_iterator_get_current_token(iterator_context);
|
||||
const FONT_INFO* const font = scene_state->active_font;
|
||||
|
||||
const FONT_INFO* current_font;
|
||||
switch(plugin_state->selected_font) {
|
||||
case 0:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
case 1:
|
||||
current_font = &redHatMono_16ptFontInfo;
|
||||
break;
|
||||
case 2:
|
||||
current_font = &bedstead_17ptFontInfo;
|
||||
break;
|
||||
case 3:
|
||||
current_font = &zector_18ptFontInfo;
|
||||
break;
|
||||
case 4:
|
||||
current_font = &_712Serif_24ptFontInfo;
|
||||
break;
|
||||
case 5:
|
||||
current_font = &graph35pix_12ptFontInfo;
|
||||
break;
|
||||
case 6:
|
||||
current_font = &karmaFuture_14ptFontInfo;
|
||||
break;
|
||||
case 7:
|
||||
current_font = &funclimbingDemo_18ptFontInfo;
|
||||
break;
|
||||
case 8:
|
||||
current_font = &dPComic_18ptFontInfo;
|
||||
break;
|
||||
case 9:
|
||||
current_font = &pixelFlag_18ptFontInfo;
|
||||
break;
|
||||
default:
|
||||
current_font = &modeNine_15ptFontInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t char_width = current_font->charInfo[0].width;
|
||||
uint8_t char_width = font->charInfo[0].width;
|
||||
scene_state->ui_precalculated_dimensions.code_total_length =
|
||||
current_token->digits * (char_width + current_font->spacePixels);
|
||||
current_token->digits * (char_width + font->spacePixels);
|
||||
scene_state->ui_precalculated_dimensions.code_offset_x =
|
||||
(SCREEN_WIDTH - scene_state->ui_precalculated_dimensions.code_total_length) >> 1;
|
||||
scene_state->ui_precalculated_dimensions.code_offset_x_inc =
|
||||
char_width + current_font->spacePixels;
|
||||
scene_state->ui_precalculated_dimensions.code_offset_y =
|
||||
SCREEN_HEIGHT_CENTER - (current_font->height >> 1);
|
||||
SCREEN_HEIGHT_CENTER - (font->height >> 1);
|
||||
|
||||
if(time_left) {
|
||||
notification_message(
|
||||
@@ -284,11 +201,11 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||
scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start(
|
||||
scene_state->last_code,
|
||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
scene_state->last_code, TokenDigitsCountMax + 1, scene_state->last_code_update_sync);
|
||||
}
|
||||
|
||||
scene_state->active_font = available_fonts[plugin_state->active_font_index];
|
||||
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
|
||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||
@@ -298,7 +215,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
|
||||
totp_bt_type_code_worker_start(
|
||||
plugin_state->bt_type_code_worker_context,
|
||||
scene_state->last_code,
|
||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||
TokenDigitsCountMax + 1,
|
||||
scene_state->last_code_update_sync);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "bt_type_code.h"
|
||||
#include <furi_hal_bt.h>
|
||||
#include <furi_hal_bt_hid.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include <bt/bt_service/bt_i.h>
|
||||
#include <furi/core/thread.h>
|
||||
#include <furi/core/mutex.h>
|
||||
#include <furi/core/string.h>
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../type_code_common.h"
|
||||
#include "../../features_config.h"
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH
|
||||
#define TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE
|
||||
#endif
|
||||
@@ -27,7 +27,7 @@ struct TotpBtTypeCodeWorkerContext {
|
||||
Bt* bt;
|
||||
bool is_advertising;
|
||||
bool is_connected;
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
char previous_bt_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN];
|
||||
uint8_t previous_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
||||
#endif
|
||||
@@ -37,7 +37,7 @@ static inline bool totp_type_code_worker_stop_requested() {
|
||||
return furi_thread_flags_get() & TotpBtTypeCodeWorkerEventStop;
|
||||
}
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
||||
uint8_t max_i;
|
||||
size_t uid_size = furi_hal_version_uid_size();
|
||||
@@ -47,7 +47,7 @@ static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
||||
max_i = TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN;
|
||||
}
|
||||
|
||||
const uint8_t* uid = furi_hal_version_uid();
|
||||
const uint8_t* uid = (const uint8_t*)UID64_BASE; //-V566
|
||||
memcpy(mac, uid, max_i);
|
||||
for(uint8_t i = max_i; i < TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN; i++) {
|
||||
mac[i] = 0;
|
||||
@@ -159,7 +159,7 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_storage_path(context->bt, TOTP_BT_KEYS_STORAGE_PATH);
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
memcpy(
|
||||
&context->previous_bt_name[0],
|
||||
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
|
||||
@@ -182,7 +182,7 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
|
||||
furi_hal_bt_start_advertising();
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
bt_enable_peer_key_update(context->bt);
|
||||
#endif
|
||||
|
||||
@@ -209,7 +209,7 @@ void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_default_path(context->bt);
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_UL_XFW
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME_UL
|
||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, context->previous_bt_name);
|
||||
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, context->previous_bt_mac);
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@ struct TotpGenerateCodeWorkerContext {
|
||||
void* on_code_lifetime_changed_handler_context;
|
||||
};
|
||||
|
||||
static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY";
|
||||
static const char STEAM_ALGO_ALPHABET[] = "23456789BCDFGHJKMNPQRTVWXY";
|
||||
|
||||
static void
|
||||
int_token_to_str(uint64_t i_token_code, char* str, TokenDigitsCount len, TokenHashAlgo algo) {
|
||||
@@ -30,7 +30,7 @@ static void
|
||||
if(i_token_code == OTP_ERROR) {
|
||||
memset(str, '-', len);
|
||||
} else {
|
||||
if(algo == STEAM) {
|
||||
if(algo == TokenHashAlgoSteam) {
|
||||
char* s = str;
|
||||
for(uint8_t i = 0; i < len; i++, s++) {
|
||||
*s = STEAM_ALGO_ALPHABET[i_token_code % 26];
|
||||
@@ -48,12 +48,12 @@ static void
|
||||
|
||||
static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
||||
switch(algo) {
|
||||
case SHA1:
|
||||
case STEAM:
|
||||
case TokenHashAlgoSha1:
|
||||
case TokenHashAlgoSteam:
|
||||
return TOTP_ALGO_SHA1;
|
||||
case SHA256:
|
||||
case TokenHashAlgoSha256:
|
||||
return TOTP_ALGO_SHA256;
|
||||
case SHA512:
|
||||
case TokenHashAlgoSha512:
|
||||
return TOTP_ALGO_SHA512;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -11,7 +11,7 @@ void infrared_scene_universal_projector_on_enter(void* context) {
|
||||
|
||||
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/projectors.ir"));
|
||||
//TODO Improve Projectors universal remote
|
||||
button_panel_reserve(button_panel, 2, 2);
|
||||
button_panel_reserve(button_panel, 2, 3);
|
||||
uint32_t i = 0;
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
@@ -61,6 +61,30 @@ void infrared_scene_universal_projector_on_enter(void* context) {
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
101,
|
||||
&I_Play_25x27,
|
||||
&I_Play_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "Play");
|
||||
button_panel_add_item(
|
||||
button_panel,
|
||||
i,
|
||||
1,
|
||||
2,
|
||||
36,
|
||||
101,
|
||||
&I_Pause_25x27,
|
||||
&I_Pause_hvr_25x27,
|
||||
infrared_scene_universal_common_item_callback,
|
||||
context);
|
||||
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
||||
|
||||
button_panel_add_label(button_panel, 10, 11, FontPrimary, "Projector");
|
||||
button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");
|
||||
|
||||
@@ -209,7 +209,7 @@ int32_t about_settings_app(void* p) {
|
||||
screen_index--;
|
||||
}
|
||||
} else if(screen_result == DialogMessageButtonRight) {
|
||||
if(screen_index < about_screens_count) {
|
||||
if(screen_index < about_screens_count - 1) {
|
||||
screen_index++;
|
||||
}
|
||||
} else if(screen_result == DialogMessageButtonBack) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 14th Jul, 2023
|
||||
# Last Checked 14th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
# Model: Electrolux EACM-16 HP/N3
|
||||
name: Off
|
||||
@@ -769,3 +769,40 @@ type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 3204 9889 537 1587 491 529 512 544 489 545 489 1573 510 530 511 543 491 552 490 538 511 543 491 543 491 532 509 543 491 1587 489 537 512 543 491 1577 490 543 491 543 491 544 489 543 491 1586 489 544 490 1587 489 539 510 543 491 543 491 1586 490
|
||||
#
|
||||
# Model: Daikin FTXC35DV1B
|
||||
name: Off
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 530 315 532 314 532 314 532 314 532 314 506 340 561 24780 3568 1647 507 1213 535 313 534 340 506 340 506 1212 507 339 507 339 506 339 506 339 506 1214 505 341 504 1215 505 1216 504 343 503 1217 503 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1219 501 345 501 344 502 345 501 1219 501 1219 501 345 501 344 502 344 502 345 501 344 502 345 501 344 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 501 1219 501 34807 3563 1652 502 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1219 501 344 502 1218 502 1219 501 344 502 1219 501 1218 502 1219 501 1219 501 1219 501 345 501 344 502 1219 501 345 501 344 502 345 501 344 502 344 502 345 501 345 501 345 501 344 502 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1219 501 345 501 345 501 1219 501 1219 501 345 501 1219 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1220 500 346 500 345 501 346 500 346 500 34806 3564 1652 502 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1219 501 1218 502 344 502 345 501 1219 501 345 501 344 502 345 501 344 502 344 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 346 500 345 501 345 501 345 501 345 501 346 500 346 500 346 500 346 500 346 500 1220 499 346 500 1220 499 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 346 500 1221 499 1221 499 1221 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 1245 475 1222 498 1245 475 371 475 348 498 348 498 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 372 474 372 474 372 474 371 475 371 475 1246 474 371 475 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 371 475 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1246 474 1246 473 372 474 372 474 1246 474 372 474
|
||||
#
|
||||
name: Dh
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 536 339 507 311 535 312 534 312 534 312 534 339 507 24807 3710 1507 594 1156 563 305 543 304 542 304 570 1126 592 304 515 304 542 304 542 304 542 1155 564 304 541 1158 505 1215 505 342 504 1217 503 1217 503 1218 502 1218 502 1218 502 344 502 343 503 1218 502 343 503 343 503 344 502 344 502 344 502 344 502 344 502 343 503 343 503 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 1218 502 1218 501 344 502 1218 502 344 502 1218 502 1218 502 34800 3564 1651 503 1217 503 343 503 344 502 343 503 1217 503 343 503 343 503 344 502 344 502 1218 502 344 502 1217 503 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 344 502 1218 502 1218 502 344 502 1218 502 1219 501 1219 501 345 501 344 502 344 502 344 502 344 502 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 34805 3565 1650 503 1216 503 343 503 343 503 344 502 1217 503 343 503 344 502 343 503 343 503 1217 503 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 1218 502 344 502 1218 501 344 502 344 502 344 502 345 501 344 502 345 501 344 502 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 346 500 345 501 345 501 346 500 370 476 346 500 346 500 346 500 370 476 346 500 346 500 346 500 346 500 1221 499 1244 476 1244 476 370 476 346 500 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1244 476 1244 476 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1244 476 370 476 1245 475 370 476 371 475 370 476 1245 475 1245 475 371 475 371 475 370 476 370 476 370 476 370 476 370 476 371 475 370 476 371 475 371 475 371 475 371 475 370 476 371 475 371 475 371 475 1245 475 1245 475 1245 475 371 475 371 475 1245 475 371 475
|
||||
#
|
||||
name: Cool_hi
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 507 340 559 306 487 341 530 315 531 313 561 305 541 24776 3569 1646 508 1212 537 340 506 340 506 340 506 1213 507 339 507 339 506 339 506 340 505 1214 505 341 504 1215 504 1216 503 343 503 1217 502 1218 502 1218 502 1218 502 1218 501 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1219 501 1218 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 501 1219 501 34800 3563 1652 502 1217 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 501 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 345 501 345 501 344 502 345 501 344 502 345 501 345 501 345 501 344 502 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 1219 501 345 501 345 501 1219 501 1219 501 345 501 1219 500 1219 500 1219 500 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1220 500 346 500 346 500 346 500 346 500 34808 3564 1652 503 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 345 501 344 502 1218 502 345 501 1218 502 1219 501 344 502 1219 501 1219 501 1219 501 1219 501 1219 501 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 500 345 501 345 501 1219 500 1219 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1219 501 346 500 346 500 345 501 345 501 346 500 346 500 346 500 345 501 346 500 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 346 500 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 347 499 346 500 1221 499 1245 475 1221 499 347 499 347 499 347 499 348 498 347 499 348 498 348 498 371 475 348 498 1222 498 1245 475 1245 475 348 498 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 372 474 372 474 372 474 371 475 1245 474 372 474 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 372 474 372 474 372 474 1247 473 1247 473
|
||||
#
|
||||
name: Cool_lo
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 533 311 535 312 534 312 534 313 533 310 536 312 534 24804 3705 1509 593 1129 590 305 542 305 542 305 569 1127 590 304 514 305 541 304 542 305 541 1155 564 305 540 1157 561 1159 504 341 504 1217 503 1217 503 1217 503 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 345 501 1218 502 1218 502 1218 502 344 502 1219 501 345 501 1219 501 1219 501 34806 3565 1650 503 1217 502 343 503 343 503 343 503 1217 503 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1219 501 344 502 1218 502 344 502 1219 501 1218 501 345 501 1218 501 1219 501 1218 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 34805 3565 1651 503 1217 502 343 503 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 1218 502 1219 501 1218 502 345 501 344 502 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 346 500 346 500 345 501 345 501 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 1221 499 1221 498 346 500 346 500 370 476 346 500 347 499 347 499 370 476 370 476 370 476 1244 476 1244 476 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 371 475 370 476 370 476 370 476 371 475 370 476 370 476 370 476 370 476 1244 476 371 475 1245 475 370 476 371 475 371 475 1245 475 1245 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 476 371 475 1245 475 1245 475 371 475 371 475 1246 474 1245 475
|
||||
#
|
||||
name: Heat_lo
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 535 313 533 311 535 311 535 312 534 312 534 313 533 24805 3711 1506 592 1129 592 305 543 305 540 305 569 1126 592 304 514 304 542 304 541 304 485 1213 507 340 506 1214 506 1215 505 342 504 1217 503 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 503 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 503 344 502 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 502 1219 502 34818 3566 1651 503 1217 503 343 503 344 502 344 502 1218 502 344 502 344 502 344 502 344 503 1218 502 344 502 1218 503 1218 502 344 502 1218 502 1218 503 1218 503 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 345 501 344 502 344 502 1219 501 345 501 345 502 1219 501 345 501 1219 502 1219 502 1219 502 344 502 1219 501 1219 502 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 345 501 1219 501 345 501 345 501 345 501 34812 3566 1651 503 1217 503 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 503 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1219 501 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 345 501 344 502 345 501 345 501 1219 502 345 501 345 501 1219 502 345 501 345 501 1219 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 502 345 501 345 501 345 501 346 500 345 501 345 501 345 501 345 501 345 501 1220 500 346 500 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 346 500 347 499 347 499 370 476 1244 476 1221 499 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1245 475 1245 476 1245 475 371 475 370 476 370 476 371 475 371 475 370 476 370 476 371 475 371 476 370 476 370 476 371 475 371 475 371 475 371 475 371 475 1245 475 371 475 1245 475 371 475 371 475 371 475 1245 475 1245 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 476 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 1245 475 1245 475 1245 475 371 475 1245 475 1246 474
|
||||
#
|
||||
name: Heat_hi
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 535 314 532 314 533 313 533 312 534 313 533 312 508 24840 3569 1647 508 1213 536 342 505 342 504 341 505 1214 506 340 506 340 506 340 505 340 506 1214 506 341 504 1216 504 1217 503 343 503 1218 502 1219 501 1219 502 1219 502 1219 502 345 502 344 502 1219 502 345 501 345 502 345 502 345 501 345 501 345 501 345 501 345 501 345 502 345 501 1219 502 345 501 1219 501 345 502 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1220 500 1219 501 1220 500 345 501 1220 500 345 501 1220 501 1220 500 34815 3564 1653 502 1218 502 344 502 345 501 344 502 1219 501 345 501 345 501 345 501 345 501 1219 502 345 501 1219 502 1220 501 345 502 1219 501 1219 502 1219 501 1219 502 1219 502 345 501 345 501 1220 501 345 502 345 501 345 501 345 501 345 501 345 501 345 502 345 501 345 502 345 501 345 501 1220 501 345 501 345 501 345 501 345 501 1220 500 345 501 346 501 1220 500 1220 501 345 501 345 501 346 500 1220 500 1220 500 1220 500 1220 500 346 500 346 500 346 500 345 501 346 500 345 501 1220 500 346 500 1220 500 1220 500 1220 500 346 500 346 500 346 500 34816 3565 1653 502 1219 501 344 502 345 501 345 501 1219 502 345 501 345 502 345 501 345 501 1219 501 345 501 1219 502 1219 501 345 501 1219 502 1219 501 1219 501 1219 501 1219 501 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1220 501 346 501 345 501 1220 501 346 500 346 500 1220 500 346 500 345 501 346 500 1220 500 1220 500 1220 501 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 346 500 1220 500 347 499 346 500 346 500 346 500 347 499 347 499 346 500 346 500 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 1222 498 1222 499 1222 498 347 499 348 498 348 498 347 499 371 475 348 498 348 498 348 498 371 475 1222 498 1246 474 1246 474 372 475 371 475 372 474 372 474 348 498 371 475 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1247 473 372 474 1246 474 1246 474 1246 474
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 13th Jul, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
@@ -3728,3 +3728,27 @@ type: parsed
|
||||
protocol: RC5
|
||||
address: 15 00 00 00
|
||||
command: 35 00 00 00
|
||||
#
|
||||
name: Mute
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 18 00 00 00
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 1D 00 00 00
|
||||
#
|
||||
name: Vol_up
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 12 00 00 00
|
||||
#
|
||||
name: Vol_dn
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 0A 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 13th Jul, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
name: Power
|
||||
type: raw
|
||||
@@ -1881,3 +1881,33 @@ type: parsed
|
||||
protocol: NEC
|
||||
address: 30 00 00 00
|
||||
command: 87 00 00 00
|
||||
#
|
||||
name: Power
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1255 435 1257 435 415 1278 1257 440 1256 435 415 1278 415 1278 415 1279 414 1279 414 1279 414 1278 1257 7176 1257 436 1256 435 415 1279 1256 438 1258 437 413 1279 414 1278 415 1278 415 1279 414 1279 414 1278 1257 7174 1256 436 1256 437 413 1278 1257 439 1257 435 415 1278 415 1278 415 1277 416 1279 414 1278 415 1278 1256 7175 1257 435 1257 435 415 1279 1256 440 1256 435 415 1278 415 1278 415 1278 415 1278 415 1280 413 1278 1257
|
||||
#
|
||||
name: Speed_up
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1284 409 1283 408 440 1253 1284 411 1285 407 441 1254 439 1253 440 1253 440 1251 442 1252 1285 409 439 7991 1285 409 1283 408 440 1253 1284 411 1285 407 441 1255 438 1253 440 1252 441 1251 442 1254 1283 407 441 7994 1283 410 1282 409 439 1254 1283 413 1283 409 439 1253 440 1253 440 1253 440 1253 440 1253 1284 407 441 7996 1284 409 1283 408 440 1253 1284 412 1284 408 440 1253 440 1253 440 1251 442 1253 440 1253 1284 409 439 7996 1284 407 1285 408 440 1254 1283 411 1285 409 439 1254 439 1253 440 1252 441 1253 440 1253 1284 408 440 7996 1284 408 1284 409 439 1255 1282 411 1285 408 440 1254 439 1252 441 1252 441 1254 439 1253 1284 407 441
|
||||
#
|
||||
name: Mode
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1251 439 1253 437 414 1282 1252 441 1255 436 415 1279 414 1280 413 1280 413 1279 1255 437 414 1279 414 8020 1253 438 1255 438 413 1281 1253 441 1255 438 413 1280 413 1279 414 1279 414 1280 1254 437 414 1280 413 8024 1253 438 1254 437 414 1281 1253 440 1256 437 414 1279 414 1279 414 1278 415 1280 1254 437 414 1280 413 8023 1254 440 1252 436 415 1279 1255 441 1255 436 415 1279 414 1279 414 1279 414 1279 1255 437 414 1279 414 8024 1253 437 1256 437 414 1280 1254 441 1255 437 414 1278 415 1280 413 1280 413 1280 1254 437 414 1279 414 8023 1254 438 1255 436 415 1280 1255 441 1255 436 415 1279 414 1279 414 1279 414 1280 1254 436 415 1280 413
|
||||
#
|
||||
name: Timer
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1252 437 1255 438 519 1174 1255 441 1255 437 518 1175 519 1173 520 1175 1253 437 518 1175 519 1175 518 7917 1253 438 1254 438 413 1281 1253 440 1256 437 414 1279 465 1228 465 1228 1254 436 415 1279 465 1227 466 7969 1253 438 1254 438 413 1280 1254 440 1256 436 415 1280 413 1278 466 1229 1254 437 414 1279 414 1278 415 8024 1252 437 1255 436 415 1279 1255 440 1256 437 414 1279 414 1279 414 1279 1255 437 414 1279 414 1278 415
|
||||
#
|
||||
name: Rotate
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1253 434 1258 435 492 1200 1258 438 1258 434 498 1194 494 1202 1257 433 494 1200 493 1200 493 1200 493 7940 1259 434 1258 433 493 1200 1259 438 1258 433 493 1199 494 1200 1259 434 492 1200 493 1200 493 1199 494 7939 1258 435 1257 434 497 1196 1258 437 1259 433 498 1196 492 1201 1258 434 497 1197 491 1200 493 1201 492 7941 1258 434 1258 435 495 1197 1258 437 1259 433 497 1197 497 1196 1259 434 496 1197 496 1197 496 1196 497 7939 1258 435 1257 434 495 1198 1258 438 1258 434 495 1198 495 1199 1257 435 494 1199 494 1197 496 1197 496
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 16th Jun, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
# ON
|
||||
name: Power
|
||||
@@ -988,3 +988,93 @@ type: parsed
|
||||
protocol: NEC
|
||||
address: 02 00 00 00
|
||||
command: 11 00 00 00
|
||||
#
|
||||
name: Mute
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 87 4E 00 00
|
||||
command: 51 AE 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 30 00 00
|
||||
command: A8 57 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 30 00 00
|
||||
command: A9 56 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 83 55 00 00
|
||||
command: 5E A1 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 83 55 00 00
|
||||
command: 5B A4 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 00 00 00 00
|
||||
command: 93 00 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 00 00 00 00
|
||||
command: 93 00 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 15 00 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 15 00 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: B8 57 00 00
|
||||
command: 18 E7 00 00
|
||||
#
|
||||
name: Play
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.33
|
||||
data: 8981 4411 532 1616 557 1592 557 465 556 465 556 466 555 467 554 468 554 1595 554 467 554 468 554 1595 554 467 580 1569 581 1568 581 1568 581 1569 580 441 581 1569 580 442 580 1570 579 1594 555 467 555 443 579 442 580 1594 554 467 555 1594 555 467 555 468 554 1595 554 1595 528 1620 529 42169 9008 2106 531
|
||||
#
|
||||
name: Pause
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.33
|
||||
data: 8981 4411 532 1616 557 1592 557 465 556 465 556 466 555 467 554 468 554 1595 554 467 554 468 554 1595 554 467 580 1569 581 1568 581 1568 581 1569 580 441 581 1569 580 442 580 1570 579 1594 555 467 555 443 579 442 580 1594 554 467 555 1594 555 467 555 468 554 1595 554 1595 528 1620 529 42169 9008 2106 531
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 31 00 00 00
|
||||
command: 41 00 00 00
|
||||
#
|
||||
name: Pause
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 31 00 00 00
|
||||
command: 41 00 00 00
|
||||
#
|
||||
name: Play
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 01 00 00 00
|
||||
command: 03 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 1st Jul, 2023
|
||||
# Last Checked 13th Jul, 2023
|
||||
# Last Updated 24th Jul, 2023
|
||||
# Last Checked 24th Jul, 2023
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
@@ -2275,3 +2275,73 @@ type: parsed
|
||||
protocol: NEC
|
||||
address: A0 00 00 00
|
||||
command: 5F 00 00 00
|
||||
#
|
||||
# Xiaomi TV
|
||||
#
|
||||
name: Power
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1126 497 708 498 706 1433 708 1433 707 497 707 1458 707 497 707 1434 681 523 681 1459 681 1460 680 9808 1100 525 677 527 677 1464 676 1465 675 529 675 1466 674 530 675 1466 675 530 674 1466 674 1466 675 9814 1095 529 675 529 675 1466 675 1466 674 530 674 1466 675 530 674 1466 674 530 674 1466 675 1466 674 9814 1095 530 674 530 674 1466 674 1466 675 530 674 1467 674 530 674 1467 674 530 674 1467 674 1467 674 9814 1095 530 674 530 674 1467 674 1467 673 530 674 1467 673 531 674 1467 673 530 675 1467 673 1467 674 9814 1095 530 674 530 674 1467 674 1467 673 531 673 1467 674 531 673 1467 673 531 673 1467 673 1467 674
|
||||
#
|
||||
name: Vol_up
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1126 496 707 1122 705 499 704 811 704 1124 704 502 701 502 702 1461 678 1150 677 527 677 527 676 12307 1096 529 675 1154 674 530 674 842 674 1155 673 530 674 530 674 1466 674 1154 674 531 673 530 674 12309 1094 530 674 1155 673 531 673 843 673 1155 673 531 673 530 674 1467 673 1155 673 530 674 531 673 12309 1094 530 674 1155 673 531 673 843 673 1155 673 531 673 531 673 1467 673 1155 673 531 673 531 673 12309 1094 531 673 1155 673 531 673 843 673 1155 673 531 673 531 673 1467 673 1155 673 531 673 531 673 12310 1093 531 673 1156 672 532 672 844 672 1156 672 532 672 532 672 1468 672 1157 671 532 672 532 672
|
||||
#
|
||||
name: Vol_dn
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1096 528 676 1152 676 529 675 842 673 1155 674 530 674 530 674 1466 674 1467 673 531 674 843 673 11688 1094 530 674 1156 673 532 673 844 672 1156 673 531 673 531 674 1467 673 1468 673 531 673 843 675 11686 1095 530 674 1155 671 534 673 843 673 1156 672 532 673 531 674 1468 672 1468 673 530 674 843 673 11689 1092 532 672 1157 673 531 673 844 673 1155 673 531 674 530 673 1468 673 1467 674 531 673 844 671 11690 1093 532 673 1155 673 533 672 844 672 1156 672 531 673 532 672 1468 673 1468 673 531 673 844 671 11688 1095 531 672 1182 647 532 672 845 672 1156 672 532 671 534 672 1469 670 1469 671 534 672 845 671
|
||||
#
|
||||
name: Ch_next
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1097 505 699 1154 673 531 673 842 675 1156 672 529 675 532 672 842 674 843 674 1156 672 1466 674 11688 1094 531 673 1157 671 531 673 844 671 1156 648 557 672 533 674 842 673 844 672 1156 673 1467 674 11687 1094 531 674 1157 670 534 671 843 674 1156 673 530 672 534 673 844 672 845 671 1158 671 1467 670 11690 1094 531 671 1158 671 531 673 844 674 1155 673 530 673 532 673 842 672 845 646 1184 699 1440 673 11687 1094 532 671 1157 672 531 673 844 672 1155 674 531 673 531 672 845 672 844 672 1157 670 1470 645 11715 1093 531 674 1155 673 531 673 870 647 1156 673 531 674 557 647 843 672 845 672 1156 673 1467 673
|
||||
#
|
||||
name: Ch_prev
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 1119 528 675 1154 647 558 674 841 675 1153 675 531 673 532 673 843 673 1155 675 1153 674 531 673 12312 1120 505 672 1156 673 532 673 844 673 1155 673 532 671 534 672 842 675 1155 670 1158 673 530 674 12312 1093 532 671 1156 675 530 672 845 672 1156 673 533 671 533 670 846 672 1156 674 1154 674 529 675 12312 1093 557 646 1182 646 532 674 843 673 1181 646 534 672 532 674 842 673 1158 670 1156 674 530 673 12315 1091 530 674 1155 673 530 673 844 673 1157 644 559 673 532 672 844 670 1157 672 1158 672 532 672 12313 1093 533 671 1157 672 532 673 845 671 1157 670 558 647 532 646 871 672 1157 671 1181 646 534 671
|
||||
#
|
||||
# Daewoo TV
|
||||
#
|
||||
name: Power
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 82 00 00 00
|
||||
#
|
||||
name: Vol_up
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 9F 00 00 00
|
||||
#
|
||||
name: Vol_dn
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 8B 00 00 00
|
||||
#
|
||||
name: Ch_next
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 9B 00 00 00
|
||||
#
|
||||
name: Ch_prev
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 8F 00 00 00
|
||||
#
|
||||
name: Mute
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: D0 00 00 00
|
||||
|
||||
+46
-39
@@ -890,16 +890,10 @@ static void nfc_worker_mf_classic_key_attack(
|
||||
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);
|
||||
FURI_LOG_D(TAG, "Trying A key for sector %d, key: %012llX", i, 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 A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
||||
FURI_LOG_D(TAG, "Key A found: %012llX", key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
|
||||
uint64_t found_key;
|
||||
@@ -912,18 +906,13 @@ static void nfc_worker_mf_classic_key_attack(
|
||||
}
|
||||
}
|
||||
}
|
||||
furi_hal_nfc_sleep();
|
||||
}
|
||||
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);
|
||||
FURI_LOG_D(TAG, "Trying B key for sector %d, key: %012llX", i, 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 B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
||||
FURI_LOG_D(TAG, "Key B found: %012llX", key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
@@ -971,8 +960,9 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context);
|
||||
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
||||
if(mf_classic_is_sector_read(data, i)) continue;
|
||||
bool is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA);
|
||||
bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||
mf_classic_is_key_found(data, i, MfClassicKeyB))
|
||||
continue;
|
||||
uint16_t key_index = 0;
|
||||
while(mf_classic_dict_get_next_key(dict, &key)) {
|
||||
FURI_LOG_T(TAG, "Key %d", key_index);
|
||||
@@ -990,19 +980,12 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i);
|
||||
deactivated = true;
|
||||
}
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"Try to auth to sector %d with key %04lx%08lx",
|
||||
i,
|
||||
(uint32_t)(key >> 32),
|
||||
(uint32_t)key);
|
||||
if(!is_key_a_found) {
|
||||
is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA);
|
||||
FURI_LOG_D(TAG, "Try to auth to sector %d with key %012llX", i, key);
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
||||
if(mf_classic_authenticate_skip_activate(
|
||||
&tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(
|
||||
TAG, "Key A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
||||
FURI_LOG_D(TAG, "Key A found: %012llX", key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
|
||||
uint64_t found_key;
|
||||
@@ -1032,17 +1015,35 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||
memcmp(sec_trailer->key_a, current_key, 6) == 0) {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyA);
|
||||
is_key_a_found = false;
|
||||
FURI_LOG_D(TAG, "Key %dA not found in attack", i);
|
||||
if(!mf_classic_authenticate_skip_activate(
|
||||
&tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyA);
|
||||
FURI_LOG_D(TAG, "Key %dA not found in attack", i);
|
||||
}
|
||||
}
|
||||
furi_hal_nfc_sleep();
|
||||
deactivated = true;
|
||||
}
|
||||
if(!is_key_b_found) {
|
||||
is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
||||
uint64_t found_key;
|
||||
if(nfc_worker_mf_get_b_key_from_sector_trailer(
|
||||
&tx_rx, i, key, &found_key)) {
|
||||
FURI_LOG_D(TAG, "Found B key via reading sector %d", i);
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, found_key);
|
||||
|
||||
if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, found_key, &tx_rx, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(mf_classic_authenticate_skip_activate(
|
||||
&tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) {
|
||||
FURI_LOG_D(
|
||||
TAG, "Key B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
||||
FURI_LOG_D(TAG, "Key B found: %012llX", key);
|
||||
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);
|
||||
@@ -1058,12 +1059,18 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyB) &&
|
||||
memcmp(sec_trailer->key_b, current_key, 6) == 0) {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyB);
|
||||
is_key_b_found = false;
|
||||
FURI_LOG_D(TAG, "Key %dB not found in attack", i);
|
||||
if(!mf_classic_authenticate_skip_activate(
|
||||
&tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) {
|
||||
mf_classic_set_key_not_found(data, i, MfClassicKeyB);
|
||||
FURI_LOG_D(TAG, "Key %dB not found in attack", i);
|
||||
}
|
||||
furi_hal_nfc_sleep();
|
||||
deactivated = true;
|
||||
}
|
||||
}
|
||||
if(is_key_a_found && is_key_b_found) break;
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||
mf_classic_is_key_found(data, i, MfClassicKeyB))
|
||||
break;
|
||||
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
|
||||
} else {
|
||||
if(!card_removed_notified) {
|
||||
|
||||
Reference in New Issue
Block a user