|
@@ -11,7 +11,7 @@
|
|
|
#include "qrcode.h"
|
|
#include "qrcode.h"
|
|
|
|
|
|
|
|
#define TAG "qrcode"
|
|
#define TAG "qrcode"
|
|
|
-#define QRCODE_FOLDER ANY_PATH("qrcodes")
|
|
|
|
|
|
|
+#define QRCODE_FOLDER EXT_PATH("qrcodes")
|
|
|
#define QRCODE_EXTENSION ".qrcode"
|
|
#define QRCODE_EXTENSION ".qrcode"
|
|
|
#define QRCODE_FILETYPE "QRCode"
|
|
#define QRCODE_FILETYPE "QRCode"
|
|
|
#define QRCODE_FILE_VERSION 1
|
|
#define QRCODE_FILE_VERSION 1
|
|
@@ -34,22 +34,22 @@ static const uint16_t MAX_LENGTH[3][4][MAX_QRCODE_VERSION] = {
|
|
|
// Numeric
|
|
// Numeric
|
|
|
{41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772}, // Low
|
|
{41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772}, // Low
|
|
|
{34, 63, 101, 149, 202, 255, 293, 365, 432, 513, 604}, // Medium
|
|
{34, 63, 101, 149, 202, 255, 293, 365, 432, 513, 604}, // Medium
|
|
|
- {27, 48, 77, 111, 144, 178, 207, 259, 312, 364, 427}, // Quartile
|
|
|
|
|
- {17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331}, // High
|
|
|
|
|
|
|
+ {27, 48, 77, 111, 144, 178, 207, 259, 312, 364, 427}, // Quartile
|
|
|
|
|
+ {17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331}, // High
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
// Alphanumeric
|
|
// Alphanumeric
|
|
|
{25, 47, 77, 114, 154, 195, 224, 279, 335, 395, 468}, // Low
|
|
{25, 47, 77, 114, 154, 195, 224, 279, 335, 395, 468}, // Low
|
|
|
- {20, 38, 61, 90, 122, 154, 178, 221, 262, 311, 366}, // Medium
|
|
|
|
|
- {16, 29, 47, 67, 87, 108, 125, 157, 189, 221, 259}, // Quartile
|
|
|
|
|
- {10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200}, // High
|
|
|
|
|
|
|
+ {20, 38, 61, 90, 122, 154, 178, 221, 262, 311, 366}, // Medium
|
|
|
|
|
+ {16, 29, 47, 67, 87, 108, 125, 157, 189, 221, 259}, // Quartile
|
|
|
|
|
+ {10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200}, // High
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
// Binary
|
|
// Binary
|
|
|
{17, 32, 53, 78, 106, 134, 154, 192, 230, 271, 321}, // Low
|
|
{17, 32, 53, 78, 106, 134, 154, 192, 230, 271, 321}, // Low
|
|
|
- {14, 26, 42, 62, 84, 106, 122, 152, 180, 213, 251}, // Medium
|
|
|
|
|
- {11, 20, 32, 46, 60, 74, 86, 108, 130, 151, 177}, // Quartile
|
|
|
|
|
- {7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137}, // High
|
|
|
|
|
|
|
+ {14, 26, 42, 62, 84, 106, 122, 152, 180, 213, 251}, // Medium
|
|
|
|
|
+ {11, 20, 32, 46, 60, 74, 86, 108, 130, 151, 177}, // Quartile
|
|
|
|
|
+ {7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137}, // High
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -81,12 +81,17 @@ typedef struct {
|
|
|
* @returns a character corresponding to the ecc level
|
|
* @returns a character corresponding to the ecc level
|
|
|
*/
|
|
*/
|
|
|
static char get_ecc_char(uint8_t ecc) {
|
|
static char get_ecc_char(uint8_t ecc) {
|
|
|
- switch (ecc) {
|
|
|
|
|
- case 0: return 'L';
|
|
|
|
|
- case 1: return 'M';
|
|
|
|
|
- case 2: return 'Q';
|
|
|
|
|
- case 3: return 'H';
|
|
|
|
|
- default: return '?';
|
|
|
|
|
|
|
+ switch(ecc) {
|
|
|
|
|
+ case 0:
|
|
|
|
|
+ return 'L';
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ return 'M';
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ return 'Q';
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ return 'H';
|
|
|
|
|
+ default:
|
|
|
|
|
+ return '?';
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -95,21 +100,21 @@ static char get_ecc_char(uint8_t ecc) {
|
|
|
* @returns the ecc level or 255 representing an unknown ECC mode
|
|
* @returns the ecc level or 255 representing an unknown ECC mode
|
|
|
*/
|
|
*/
|
|
|
static uint8_t get_ecc_value(char ecc) {
|
|
static uint8_t get_ecc_value(char ecc) {
|
|
|
- switch (ecc) {
|
|
|
|
|
- case 'L':
|
|
|
|
|
- case 'l':
|
|
|
|
|
- return 0;
|
|
|
|
|
- case 'M':
|
|
|
|
|
- case 'm':
|
|
|
|
|
- return 1;
|
|
|
|
|
- case 'Q':
|
|
|
|
|
- case 'q':
|
|
|
|
|
- return 2;
|
|
|
|
|
- case 'H':
|
|
|
|
|
- case 'h':
|
|
|
|
|
- return 3;
|
|
|
|
|
- default:
|
|
|
|
|
- return 255;
|
|
|
|
|
|
|
+ switch(ecc) {
|
|
|
|
|
+ case 'L':
|
|
|
|
|
+ case 'l':
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ case 'M':
|
|
|
|
|
+ case 'm':
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ case 'Q':
|
|
|
|
|
+ case 'q':
|
|
|
|
|
+ return 2;
|
|
|
|
|
+ case 'H':
|
|
|
|
|
+ case 'h':
|
|
|
|
|
+ return 3;
|
|
|
|
|
+ default:
|
|
|
|
|
+ return 255;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -118,12 +123,17 @@ static uint8_t get_ecc_value(char ecc) {
|
|
|
* @returns a character corresponding to the mode
|
|
* @returns a character corresponding to the mode
|
|
|
*/
|
|
*/
|
|
|
static char get_mode_char(uint8_t mode) {
|
|
static char get_mode_char(uint8_t mode) {
|
|
|
- switch (mode) {
|
|
|
|
|
- case 0: return 'N';
|
|
|
|
|
- case 1: return 'A';
|
|
|
|
|
- case 2: return 'B';
|
|
|
|
|
- case 3: return 'K';
|
|
|
|
|
- default: return '?';
|
|
|
|
|
|
|
+ switch(mode) {
|
|
|
|
|
+ case 0:
|
|
|
|
|
+ return 'N';
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ return 'A';
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ return 'B';
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ return 'K';
|
|
|
|
|
+ default:
|
|
|
|
|
+ return '?';
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -132,18 +142,18 @@ static char get_mode_char(uint8_t mode) {
|
|
|
* @returns the mode or 255 representing an unknown mode
|
|
* @returns the mode or 255 representing an unknown mode
|
|
|
*/
|
|
*/
|
|
|
static uint8_t get_mode_value(char mode) {
|
|
static uint8_t get_mode_value(char mode) {
|
|
|
- switch (mode) {
|
|
|
|
|
- case 'N':
|
|
|
|
|
- case 'n':
|
|
|
|
|
- return 0;
|
|
|
|
|
- case 'A':
|
|
|
|
|
- case 'a':
|
|
|
|
|
- return 1;
|
|
|
|
|
- case 'B':
|
|
|
|
|
- case 'b':
|
|
|
|
|
- return 2;
|
|
|
|
|
- default:
|
|
|
|
|
- return 255;
|
|
|
|
|
|
|
+ switch(mode) {
|
|
|
|
|
+ case 'N':
|
|
|
|
|
+ case 'n':
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ case 'A':
|
|
|
|
|
+ case 'a':
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ case 'B':
|
|
|
|
|
+ case 'b':
|
|
|
|
|
+ return 2;
|
|
|
|
|
+ default:
|
|
|
|
|
+ return 255;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -166,67 +176,124 @@ static void render_callback(Canvas* canvas, void* ctx) {
|
|
|
uint8_t font_height = canvas_current_font_height(canvas);
|
|
uint8_t font_height = canvas_current_font_height(canvas);
|
|
|
uint8_t width = canvas_width(canvas);
|
|
uint8_t width = canvas_width(canvas);
|
|
|
uint8_t height = canvas_height(canvas);
|
|
uint8_t height = canvas_height(canvas);
|
|
|
- if (instance->loading) {
|
|
|
|
|
- canvas_draw_str_aligned(canvas, width / 2, height / 2, AlignCenter, AlignCenter, "Loading...");
|
|
|
|
|
- } else if (instance->qrcode) {
|
|
|
|
|
|
|
+ if(instance->loading) {
|
|
|
|
|
+ canvas_draw_str_aligned(
|
|
|
|
|
+ canvas, width / 2, height / 2, AlignCenter, AlignCenter, "Loading...");
|
|
|
|
|
+ } else if(instance->qrcode) {
|
|
|
uint8_t size = instance->qrcode->size;
|
|
uint8_t size = instance->qrcode->size;
|
|
|
uint8_t pixel_size = height / size;
|
|
uint8_t pixel_size = height / size;
|
|
|
uint8_t top = (height - pixel_size * size) / 2;
|
|
uint8_t top = (height - pixel_size * size) / 2;
|
|
|
uint8_t left = ((instance->show_stats ? 65 : width) - pixel_size * size) / 2;
|
|
uint8_t left = ((instance->show_stats ? 65 : width) - pixel_size * size) / 2;
|
|
|
- for (uint8_t y = 0; y < size; y++) {
|
|
|
|
|
- for (uint8_t x = 0; x < size; x++) {
|
|
|
|
|
- if (qrcode_getModule(instance->qrcode, x, y)) {
|
|
|
|
|
- if (pixel_size == 1) {
|
|
|
|
|
|
|
+ for(uint8_t y = 0; y < size; y++) {
|
|
|
|
|
+ for(uint8_t x = 0; x < size; x++) {
|
|
|
|
|
+ if(qrcode_getModule(instance->qrcode, x, y)) {
|
|
|
|
|
+ if(pixel_size == 1) {
|
|
|
canvas_draw_dot(canvas, left + x * pixel_size, top + y * pixel_size);
|
|
canvas_draw_dot(canvas, left + x * pixel_size, top + y * pixel_size);
|
|
|
} else {
|
|
} else {
|
|
|
- canvas_draw_box(canvas, left + x * pixel_size, top + y * pixel_size, pixel_size, pixel_size);
|
|
|
|
|
|
|
+ canvas_draw_box(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ left + x * pixel_size,
|
|
|
|
|
+ top + y * pixel_size,
|
|
|
|
|
+ pixel_size,
|
|
|
|
|
+ pixel_size);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (instance->show_stats) {
|
|
|
|
|
|
|
+ if(instance->show_stats) {
|
|
|
top = 10;
|
|
top = 10;
|
|
|
left = 66;
|
|
left = 66;
|
|
|
|
|
|
|
|
FuriString* str = furi_string_alloc();
|
|
FuriString* str = furi_string_alloc();
|
|
|
|
|
|
|
|
- if (!instance->edit || instance->selected_idx == 0) {
|
|
|
|
|
|
|
+ if(!instance->edit || instance->selected_idx == 0) {
|
|
|
furi_string_printf(str, "Mod: %c", get_mode_char(instance->set_mode));
|
|
furi_string_printf(str, "Mod: %c", get_mode_char(instance->set_mode));
|
|
|
canvas_draw_str(canvas, left + 5, font_height + top, furi_string_get_cstr(str));
|
|
canvas_draw_str(canvas, left + 5, font_height + top, furi_string_get_cstr(str));
|
|
|
- if (instance->selected_idx == 0) {
|
|
|
|
|
- canvas_draw_triangle(canvas, left, top + font_height / 2, font_height - 4, 4, CanvasDirectionLeftToRight);
|
|
|
|
|
|
|
+ if(instance->selected_idx == 0) {
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ left,
|
|
|
|
|
+ top + font_height / 2,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionLeftToRight);
|
|
|
}
|
|
}
|
|
|
- if (instance->edit) {
|
|
|
|
|
|
|
+ if(instance->edit) {
|
|
|
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "Mod: B") / 2;
|
|
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "Mod: B") / 2;
|
|
|
- canvas_draw_triangle(canvas, arrow_left, top, font_height - 4, 4, CanvasDirectionBottomToTop);
|
|
|
|
|
- canvas_draw_triangle(canvas, arrow_left, top + font_height + 1, font_height - 4, 4, CanvasDirectionTopToBottom);
|
|
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas, arrow_left, top, font_height - 4, 4, CanvasDirectionBottomToTop);
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ arrow_left,
|
|
|
|
|
+ top + font_height + 1,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionTopToBottom);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!instance->edit || instance->selected_idx == 1) {
|
|
|
|
|
|
|
+ if(!instance->edit || instance->selected_idx == 1) {
|
|
|
furi_string_printf(str, "Ver: %i", instance->set_version);
|
|
furi_string_printf(str, "Ver: %i", instance->set_version);
|
|
|
- canvas_draw_str(canvas, left + 5, 2 * font_height + top + 2, furi_string_get_cstr(str));
|
|
|
|
|
- if (instance->selected_idx == 1) {
|
|
|
|
|
- canvas_draw_triangle(canvas, left, 3 * font_height / 2 + top + 2, font_height - 4, 4, CanvasDirectionLeftToRight);
|
|
|
|
|
|
|
+ canvas_draw_str(
|
|
|
|
|
+ canvas, left + 5, 2 * font_height + top + 2, furi_string_get_cstr(str));
|
|
|
|
|
+ if(instance->selected_idx == 1) {
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ left,
|
|
|
|
|
+ 3 * font_height / 2 + top + 2,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionLeftToRight);
|
|
|
}
|
|
}
|
|
|
- if (instance->edit) {
|
|
|
|
|
|
|
+ if(instance->edit) {
|
|
|
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "Ver: 8") / 2;
|
|
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "Ver: 8") / 2;
|
|
|
- canvas_draw_triangle(canvas, arrow_left, font_height + top + 2, font_height - 4, 4, CanvasDirectionBottomToTop);
|
|
|
|
|
- canvas_draw_triangle(canvas, arrow_left, 2 * font_height + top + 3, font_height - 4, 4, CanvasDirectionTopToBottom);
|
|
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ arrow_left,
|
|
|
|
|
+ font_height + top + 2,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionBottomToTop);
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ arrow_left,
|
|
|
|
|
+ 2 * font_height + top + 3,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionTopToBottom);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!instance->edit || instance->selected_idx == 2) {
|
|
|
|
|
|
|
+ if(!instance->edit || instance->selected_idx == 2) {
|
|
|
furi_string_printf(str, "ECC: %c", get_ecc_char(instance->set_ecc));
|
|
furi_string_printf(str, "ECC: %c", get_ecc_char(instance->set_ecc));
|
|
|
- canvas_draw_str(canvas, left + 5, 3 * font_height + top + 4, furi_string_get_cstr(str));
|
|
|
|
|
- if (instance->selected_idx == 2) {
|
|
|
|
|
- canvas_draw_triangle(canvas, left, 5 * font_height / 2 + top + 4, font_height - 4, 4, CanvasDirectionLeftToRight);
|
|
|
|
|
|
|
+ canvas_draw_str(
|
|
|
|
|
+ canvas, left + 5, 3 * font_height + top + 4, furi_string_get_cstr(str));
|
|
|
|
|
+ if(instance->selected_idx == 2) {
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ left,
|
|
|
|
|
+ 5 * font_height / 2 + top + 4,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionLeftToRight);
|
|
|
}
|
|
}
|
|
|
- if (instance->edit) {
|
|
|
|
|
|
|
+ if(instance->edit) {
|
|
|
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "ECC: H") / 2;
|
|
uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "ECC: H") / 2;
|
|
|
- canvas_draw_triangle(canvas, arrow_left, 2 * font_height + top + 4, font_height - 4, 4, CanvasDirectionBottomToTop);
|
|
|
|
|
- canvas_draw_triangle(canvas, arrow_left, 3 * font_height + top + 5, font_height - 4, 4, CanvasDirectionTopToBottom);
|
|
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ arrow_left,
|
|
|
|
|
+ 2 * font_height + top + 4,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionBottomToTop);
|
|
|
|
|
+ canvas_draw_triangle(
|
|
|
|
|
+ canvas,
|
|
|
|
|
+ arrow_left,
|
|
|
|
|
+ 3 * font_height + top + 5,
|
|
|
|
|
+ font_height - 4,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ CanvasDirectionTopToBottom);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -234,8 +301,9 @@ static void render_callback(Canvas* canvas, void* ctx) {
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
uint8_t margin = (height - font_height * 2) / 3;
|
|
uint8_t margin = (height - font_height * 2) / 3;
|
|
|
- canvas_draw_str_aligned(canvas, width / 2, margin, AlignCenter, AlignTop, "Could not load qrcode.");
|
|
|
|
|
- if (instance->too_long) {
|
|
|
|
|
|
|
+ canvas_draw_str_aligned(
|
|
|
|
|
+ canvas, width / 2, margin, AlignCenter, AlignTop, "Could not load qrcode.");
|
|
|
|
|
+ if(instance->too_long) {
|
|
|
canvas_set_font(canvas, FontSecondary);
|
|
canvas_set_font(canvas, FontSecondary);
|
|
|
canvas_draw_str(canvas, width / 2, margin * 2 + font_height, "Message is too long.");
|
|
canvas_draw_str(canvas, width / 2, margin * 2 + font_height, "Message is too long.");
|
|
|
}
|
|
}
|
|
@@ -252,7 +320,7 @@ static void render_callback(Canvas* canvas, void* ctx) {
|
|
|
static void input_callback(InputEvent* input_event, void* ctx) {
|
|
static void input_callback(InputEvent* input_event, void* ctx) {
|
|
|
furi_assert(input_event);
|
|
furi_assert(input_event);
|
|
|
furi_assert(ctx);
|
|
furi_assert(ctx);
|
|
|
- if (input_event->type == InputTypeShort) {
|
|
|
|
|
|
|
+ if(input_event->type == InputTypeShort) {
|
|
|
QRCodeApp* instance = ctx;
|
|
QRCodeApp* instance = ctx;
|
|
|
furi_message_queue_put(instance->input_queue, input_event, 0);
|
|
furi_message_queue_put(instance->input_queue, input_event, 0);
|
|
|
}
|
|
}
|
|
@@ -265,9 +333,9 @@ static void input_callback(InputEvent* input_event, void* ctx) {
|
|
|
*/
|
|
*/
|
|
|
static bool is_numeric(const char* str, uint16_t len) {
|
|
static bool is_numeric(const char* str, uint16_t len) {
|
|
|
furi_assert(str);
|
|
furi_assert(str);
|
|
|
- while (len > 0) {
|
|
|
|
|
|
|
+ while(len > 0) {
|
|
|
char c = str[--len];
|
|
char c = str[--len];
|
|
|
- if (c < '0' || c > '9') return false;
|
|
|
|
|
|
|
+ if(c < '0' || c > '9') return false;
|
|
|
}
|
|
}
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
@@ -279,19 +347,12 @@ static bool is_numeric(const char* str, uint16_t len) {
|
|
|
*/
|
|
*/
|
|
|
static bool is_alphanumeric(const char* str, uint16_t len) {
|
|
static bool is_alphanumeric(const char* str, uint16_t len) {
|
|
|
furi_assert(str);
|
|
furi_assert(str);
|
|
|
- while (len > 0) {
|
|
|
|
|
|
|
+ while(len > 0) {
|
|
|
char c = str[--len];
|
|
char c = str[--len];
|
|
|
- if (c >= '0' && c <= '9') continue;
|
|
|
|
|
- if (c >= 'A' && c <= 'Z') continue;
|
|
|
|
|
- if (c == ' '
|
|
|
|
|
- || c == '$'
|
|
|
|
|
- || c == '%'
|
|
|
|
|
- || c == '*'
|
|
|
|
|
- || c == '+'
|
|
|
|
|
- || c == '-'
|
|
|
|
|
- || c == '.'
|
|
|
|
|
- || c == '/'
|
|
|
|
|
- || c == ':')
|
|
|
|
|
|
|
+ if(c >= '0' && c <= '9') continue;
|
|
|
|
|
+ if(c >= 'A' && c <= 'Z') continue;
|
|
|
|
|
+ if(c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' ||
|
|
|
|
|
+ c == '/' || c == ':')
|
|
|
continue;
|
|
continue;
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
@@ -338,8 +399,15 @@ static bool rebuild_qrcode(QRCodeApp* instance, uint8_t mode, uint8_t version, u
|
|
|
uint16_t len = (uint16_t)furi_string_size(instance->message);
|
|
uint16_t len = (uint16_t)furi_string_size(instance->message);
|
|
|
instance->qrcode = qrcode_alloc(version);
|
|
instance->qrcode = qrcode_alloc(version);
|
|
|
|
|
|
|
|
- int8_t res = qrcode_initBytes(instance->qrcode, instance->qrcode->modules, (int8_t)mode, version, ecc, (uint8_t*)cstr, len);
|
|
|
|
|
- if (res != 0) {
|
|
|
|
|
|
|
+ int8_t res = qrcode_initBytes(
|
|
|
|
|
+ instance->qrcode,
|
|
|
|
|
+ instance->qrcode->modules,
|
|
|
|
|
+ (int8_t)mode,
|
|
|
|
|
+ version,
|
|
|
|
|
+ ecc,
|
|
|
|
|
+ (uint8_t*)cstr,
|
|
|
|
|
+ len);
|
|
|
|
|
+ if(res != 0) {
|
|
|
FURI_LOG_E(TAG, "Could not create qrcode");
|
|
FURI_LOG_E(TAG, "Could not create qrcode");
|
|
|
|
|
|
|
|
qrcode_free(instance->qrcode);
|
|
qrcode_free(instance->qrcode);
|
|
@@ -359,7 +427,7 @@ static bool rebuild_qrcode(QRCodeApp* instance, uint8_t mode, uint8_t version, u
|
|
|
* @param ecc Pointer to variable that will receive the maximum ECC
|
|
* @param ecc Pointer to variable that will receive the maximum ECC
|
|
|
* @returns false if the data is too long for the given mode, true otherwise.
|
|
* @returns false if the data is too long for the given mode, true otherwise.
|
|
|
*/
|
|
*/
|
|
|
-static bool find_min_version_max_ecc(uint16_t len, uint8_t mode, uint8_t *version, uint8_t *ecc) {
|
|
|
|
|
|
|
+static bool find_min_version_max_ecc(uint16_t len, uint8_t mode, uint8_t* version, uint8_t* ecc) {
|
|
|
// Figure out the smallest qrcode version that'll fit all of the data - we
|
|
// Figure out the smallest qrcode version that'll fit all of the data - we
|
|
|
// prefer the smallest version to maximize the pixel size of each module to
|
|
// prefer the smallest version to maximize the pixel size of each module to
|
|
|
// improve reader performance. Here, version is the 0-based index. The
|
|
// improve reader performance. Here, version is the 0-based index. The
|
|
@@ -367,11 +435,11 @@ static bool find_min_version_max_ecc(uint16_t len, uint8_t mode, uint8_t *versio
|
|
|
// add one later.
|
|
// add one later.
|
|
|
*ecc = ECC_LOW;
|
|
*ecc = ECC_LOW;
|
|
|
*version = 0;
|
|
*version = 0;
|
|
|
- while (*version < MAX_QRCODE_VERSION && MAX_LENGTH[mode][*ecc][*version] < len) {
|
|
|
|
|
|
|
+ while(*version < MAX_QRCODE_VERSION && MAX_LENGTH[mode][*ecc][*version] < len) {
|
|
|
(*version)++;
|
|
(*version)++;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (*version == MAX_QRCODE_VERSION) {
|
|
|
|
|
|
|
+ if(*version == MAX_QRCODE_VERSION) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -381,7 +449,7 @@ static bool find_min_version_max_ecc(uint16_t len, uint8_t mode, uint8_t *versio
|
|
|
// using it as a 0-based number here, but qrcode_initBytes will want a
|
|
// using it as a 0-based number here, but qrcode_initBytes will want a
|
|
|
// 1-based number...
|
|
// 1-based number...
|
|
|
*ecc = ECC_HIGH;
|
|
*ecc = ECC_HIGH;
|
|
|
- while (MAX_LENGTH[mode][*ecc][*version] < len) {
|
|
|
|
|
|
|
+ while(MAX_LENGTH[mode][*ecc][*version] < len) {
|
|
|
(*ecc)--;
|
|
(*ecc)--;
|
|
|
}
|
|
}
|
|
|
(*version)++;
|
|
(*version)++;
|
|
@@ -398,16 +466,21 @@ static bool find_min_version_max_ecc(uint16_t len, uint8_t mode, uint8_t *versio
|
|
|
* @param desired_ecc User selected ECC, 255 = unset
|
|
* @param desired_ecc User selected ECC, 255 = unset
|
|
|
* @returns true if the string was successfully loaded
|
|
* @returns true if the string was successfully loaded
|
|
|
*/
|
|
*/
|
|
|
-static bool qrcode_load_string(QRCodeApp* instance, FuriString* str, uint8_t desired_mode, uint8_t desired_version, uint8_t desired_ecc) {
|
|
|
|
|
|
|
+static bool qrcode_load_string(
|
|
|
|
|
+ QRCodeApp* instance,
|
|
|
|
|
+ FuriString* str,
|
|
|
|
|
+ uint8_t desired_mode,
|
|
|
|
|
+ uint8_t desired_version,
|
|
|
|
|
+ uint8_t desired_ecc) {
|
|
|
furi_assert(instance);
|
|
furi_assert(instance);
|
|
|
furi_assert(str);
|
|
furi_assert(str);
|
|
|
|
|
|
|
|
furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk);
|
|
furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
- if (instance->message) {
|
|
|
|
|
|
|
+ if(instance->message) {
|
|
|
furi_string_free(instance->message);
|
|
furi_string_free(instance->message);
|
|
|
instance->message = NULL;
|
|
instance->message = NULL;
|
|
|
}
|
|
}
|
|
|
- if (instance->qrcode) {
|
|
|
|
|
|
|
+ if(instance->qrcode) {
|
|
|
qrcode_free(instance->qrcode);
|
|
qrcode_free(instance->qrcode);
|
|
|
instance->qrcode = NULL;
|
|
instance->qrcode = NULL;
|
|
|
}
|
|
}
|
|
@@ -422,64 +495,69 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str, uint8_t des
|
|
|
uint16_t len = (uint16_t)furi_string_size(str);
|
|
uint16_t len = (uint16_t)furi_string_size(str);
|
|
|
|
|
|
|
|
instance->message = furi_string_alloc_set(str);
|
|
instance->message = furi_string_alloc_set(str);
|
|
|
- if (!instance->message) {
|
|
|
|
|
|
|
+ if(!instance->message) {
|
|
|
FURI_LOG_E(TAG, "Could not allocate message");
|
|
FURI_LOG_E(TAG, "Could not allocate message");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// figure out the minimum qrcode "mode"
|
|
// figure out the minimum qrcode "mode"
|
|
|
int8_t min_mode = MODE_BYTE;
|
|
int8_t min_mode = MODE_BYTE;
|
|
|
- if (is_numeric(cstr, len)) min_mode = MODE_NUMERIC;
|
|
|
|
|
- else if (is_alphanumeric(cstr, len)) min_mode = MODE_ALPHANUMERIC;
|
|
|
|
|
|
|
+ if(is_numeric(cstr, len))
|
|
|
|
|
+ min_mode = MODE_NUMERIC;
|
|
|
|
|
+ else if(is_alphanumeric(cstr, len))
|
|
|
|
|
+ min_mode = MODE_ALPHANUMERIC;
|
|
|
|
|
|
|
|
// determine the maximum "mode"
|
|
// determine the maximum "mode"
|
|
|
int8_t max_mode = MAX_QRCODE_MODE;
|
|
int8_t max_mode = MAX_QRCODE_MODE;
|
|
|
uint8_t min_version = 0;
|
|
uint8_t min_version = 0;
|
|
|
uint8_t max_ecc_at_min_version = 0;
|
|
uint8_t max_ecc_at_min_version = 0;
|
|
|
- while (max_mode >= min_mode && !find_min_version_max_ecc(len, (uint8_t)max_mode, &min_version, &max_ecc_at_min_version)) {
|
|
|
|
|
|
|
+ while(max_mode >= min_mode &&
|
|
|
|
|
+ !find_min_version_max_ecc(
|
|
|
|
|
+ len, (uint8_t)max_mode, &min_version, &max_ecc_at_min_version)) {
|
|
|
max_mode--;
|
|
max_mode--;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// if the max is less than the min, the message is too long
|
|
// if the max is less than the min, the message is too long
|
|
|
- if (max_mode < min_mode) {
|
|
|
|
|
|
|
+ if(max_mode < min_mode) {
|
|
|
instance->too_long = true;
|
|
instance->too_long = true;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// pick a mode based on the min/max and desired mode
|
|
// pick a mode based on the min/max and desired mode
|
|
|
- if (desired_mode == 255 || desired_mode < (uint8_t)min_mode) {
|
|
|
|
|
|
|
+ if(desired_mode == 255 || desired_mode < (uint8_t)min_mode) {
|
|
|
desired_mode = (uint8_t)min_mode;
|
|
desired_mode = (uint8_t)min_mode;
|
|
|
- } else if (desired_mode > (uint8_t)max_mode) {
|
|
|
|
|
|
|
+ } else if(desired_mode > (uint8_t)max_mode) {
|
|
|
desired_mode = (uint8_t)max_mode;
|
|
desired_mode = (uint8_t)max_mode;
|
|
|
}
|
|
}
|
|
|
- if (desired_mode != (uint8_t)max_mode) {
|
|
|
|
|
|
|
+ if(desired_mode != (uint8_t)max_mode) {
|
|
|
// if the desired mode equals the max mode, then min_version and
|
|
// if the desired mode equals the max mode, then min_version and
|
|
|
// max_ecc_at_min_version are already set appropriately by the max
|
|
// max_ecc_at_min_version are already set appropriately by the max
|
|
|
// mode loop above... otherwise, we need to calculate them... this
|
|
// mode loop above... otherwise, we need to calculate them... this
|
|
|
// should always return true because we already know the desired
|
|
// should always return true because we already know the desired
|
|
|
// mode is appropriate for the data, but, just in case...
|
|
// mode is appropriate for the data, but, just in case...
|
|
|
- if (!find_min_version_max_ecc(len, desired_mode, &min_version, &max_ecc_at_min_version)) {
|
|
|
|
|
|
|
+ if(!find_min_version_max_ecc(
|
|
|
|
|
+ len, desired_mode, &min_version, &max_ecc_at_min_version)) {
|
|
|
instance->too_long = true;
|
|
instance->too_long = true;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ensure desired version and ecc are appropriate
|
|
// ensure desired version and ecc are appropriate
|
|
|
- if (desired_version == 255 || desired_version < min_version) {
|
|
|
|
|
|
|
+ if(desired_version == 255 || desired_version < min_version) {
|
|
|
desired_version = min_version;
|
|
desired_version = min_version;
|
|
|
- } else if (desired_version > MAX_QRCODE_VERSION) {
|
|
|
|
|
|
|
+ } else if(desired_version > MAX_QRCODE_VERSION) {
|
|
|
desired_version = MAX_QRCODE_VERSION;
|
|
desired_version = MAX_QRCODE_VERSION;
|
|
|
}
|
|
}
|
|
|
- if (desired_version == min_version) {
|
|
|
|
|
- if (desired_ecc > max_ecc_at_min_version) {
|
|
|
|
|
|
|
+ if(desired_version == min_version) {
|
|
|
|
|
+ if(desired_ecc > max_ecc_at_min_version) {
|
|
|
desired_ecc = max_ecc_at_min_version;
|
|
desired_ecc = max_ecc_at_min_version;
|
|
|
}
|
|
}
|
|
|
- } else if (desired_ecc > MAX_QRCODE_ECC) {
|
|
|
|
|
|
|
+ } else if(desired_ecc > MAX_QRCODE_ECC) {
|
|
|
desired_ecc = MAX_QRCODE_ECC;
|
|
desired_ecc = MAX_QRCODE_ECC;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Build the qrcode
|
|
// Build the qrcode
|
|
|
- if (!rebuild_qrcode(instance, desired_mode, desired_version, desired_ecc)) {
|
|
|
|
|
|
|
+ if(!rebuild_qrcode(instance, desired_mode, desired_version, desired_ecc)) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -491,14 +569,14 @@ static bool qrcode_load_string(QRCodeApp* instance, FuriString* str, uint8_t des
|
|
|
instance->max_ecc_at_min_version = max_ecc_at_min_version;
|
|
instance->max_ecc_at_min_version = max_ecc_at_min_version;
|
|
|
instance->set_ecc = desired_ecc;
|
|
instance->set_ecc = desired_ecc;
|
|
|
result = true;
|
|
result = true;
|
|
|
- } while (false);
|
|
|
|
|
|
|
+ } while(false);
|
|
|
|
|
|
|
|
- if (!result) {
|
|
|
|
|
- if (instance->message) {
|
|
|
|
|
|
|
+ if(!result) {
|
|
|
|
|
+ if(instance->message) {
|
|
|
furi_string_free(instance->message);
|
|
furi_string_free(instance->message);
|
|
|
instance->message = NULL;
|
|
instance->message = NULL;
|
|
|
}
|
|
}
|
|
|
- if (instance->qrcode) {
|
|
|
|
|
|
|
+ if(instance->qrcode) {
|
|
|
qrcode_free(instance->qrcode);
|
|
qrcode_free(instance->qrcode);
|
|
|
instance->qrcode = NULL;
|
|
instance->qrcode = NULL;
|
|
|
}
|
|
}
|
|
@@ -528,12 +606,11 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
|
|
|
FlipperFormat* file = flipper_format_file_alloc(storage);
|
|
FlipperFormat* file = flipper_format_file_alloc(storage);
|
|
|
|
|
|
|
|
do {
|
|
do {
|
|
|
- if (!flipper_format_file_open_existing(file, file_path)) break;
|
|
|
|
|
|
|
+ if(!flipper_format_file_open_existing(file, file_path)) break;
|
|
|
|
|
|
|
|
uint32_t file_version = 0;
|
|
uint32_t file_version = 0;
|
|
|
- if (!flipper_format_read_header(file, temp_str, &file_version)) break;
|
|
|
|
|
- if (furi_string_cmp_str(temp_str, QRCODE_FILETYPE)
|
|
|
|
|
- || file_version > QRCODE_FILE_VERSION) {
|
|
|
|
|
|
|
+ if(!flipper_format_read_header(file, temp_str, &file_version)) break;
|
|
|
|
|
+ if(furi_string_cmp_str(temp_str, QRCODE_FILETYPE) || file_version > QRCODE_FILE_VERSION) {
|
|
|
FURI_LOG_E(TAG, "Incorrect file format or version");
|
|
FURI_LOG_E(TAG, "Incorrect file format or version");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -541,10 +618,10 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
|
|
|
uint32_t desired_mode = 255;
|
|
uint32_t desired_mode = 255;
|
|
|
uint32_t desired_version = 255;
|
|
uint32_t desired_version = 255;
|
|
|
uint32_t desired_ecc = 255;
|
|
uint32_t desired_ecc = 255;
|
|
|
- if (file_version > 0) {
|
|
|
|
|
- if (flipper_format_key_exist(file, "QRMode")) {
|
|
|
|
|
- if (flipper_format_read_string(file, "QRMode", temp_str)) {
|
|
|
|
|
- if (furi_string_size(temp_str) > 0) {
|
|
|
|
|
|
|
+ if(file_version > 0) {
|
|
|
|
|
+ if(flipper_format_key_exist(file, "QRMode")) {
|
|
|
|
|
+ if(flipper_format_read_string(file, "QRMode", temp_str)) {
|
|
|
|
|
+ if(furi_string_size(temp_str) > 0) {
|
|
|
desired_mode = get_mode_value(furi_string_get_char(temp_str, 0));
|
|
desired_mode = get_mode_value(furi_string_get_char(temp_str, 0));
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -553,9 +630,9 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (flipper_format_key_exist(file, "QRVersion")) {
|
|
|
|
|
- if (flipper_format_read_uint32(file, "QRVersion", &desired_version, 1)) {
|
|
|
|
|
- if (desired_version > MAX_QRCODE_VERSION) {
|
|
|
|
|
|
|
+ if(flipper_format_key_exist(file, "QRVersion")) {
|
|
|
|
|
+ if(flipper_format_read_uint32(file, "QRVersion", &desired_version, 1)) {
|
|
|
|
|
+ if(desired_version > MAX_QRCODE_VERSION) {
|
|
|
FURI_LOG_E(TAG, "Invalid QRVersion");
|
|
FURI_LOG_E(TAG, "Invalid QRVersion");
|
|
|
desired_version = 255;
|
|
desired_version = 255;
|
|
|
}
|
|
}
|
|
@@ -565,9 +642,9 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (flipper_format_key_exist(file, "QRECC")) {
|
|
|
|
|
- if (flipper_format_read_string(file, "QRECC", temp_str)) {
|
|
|
|
|
- if (furi_string_size(temp_str) > 0) {
|
|
|
|
|
|
|
+ if(flipper_format_key_exist(file, "QRECC")) {
|
|
|
|
|
+ if(flipper_format_read_string(file, "QRECC", temp_str)) {
|
|
|
|
|
+ if(furi_string_size(temp_str) > 0) {
|
|
|
desired_ecc = get_ecc_value(furi_string_get_char(temp_str, 0));
|
|
desired_ecc = get_ecc_value(furi_string_get_char(temp_str, 0));
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -577,14 +654,14 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!flipper_format_read_string(file, "Message", temp_str)) {
|
|
|
|
|
|
|
+ if(!flipper_format_read_string(file, "Message", temp_str)) {
|
|
|
FURI_LOG_E(TAG, "Message is missing");
|
|
FURI_LOG_E(TAG, "Message is missing");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- if (file_version > 0) {
|
|
|
|
|
|
|
+ if(file_version > 0) {
|
|
|
FuriString* msg_cont = furi_string_alloc();
|
|
FuriString* msg_cont = furi_string_alloc();
|
|
|
- while (flipper_format_key_exist(file, "Message")) {
|
|
|
|
|
- if (!flipper_format_read_string(file, "Message", msg_cont)) {
|
|
|
|
|
|
|
+ while(flipper_format_key_exist(file, "Message")) {
|
|
|
|
|
+ if(!flipper_format_read_string(file, "Message", msg_cont)) {
|
|
|
FURI_LOG_E(TAG, "Could not read next Message");
|
|
FURI_LOG_E(TAG, "Could not read next Message");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -594,12 +671,17 @@ static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) {
|
|
|
furi_string_free(msg_cont);
|
|
furi_string_free(msg_cont);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!qrcode_load_string(instance, temp_str, (uint8_t)desired_mode, (uint8_t)desired_version, (uint8_t)desired_ecc)) {
|
|
|
|
|
|
|
+ if(!qrcode_load_string(
|
|
|
|
|
+ instance,
|
|
|
|
|
+ temp_str,
|
|
|
|
|
+ (uint8_t)desired_mode,
|
|
|
|
|
+ (uint8_t)desired_version,
|
|
|
|
|
+ (uint8_t)desired_ecc)) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
result = true;
|
|
result = true;
|
|
|
- } while (false);
|
|
|
|
|
|
|
+ } while(false);
|
|
|
|
|
|
|
|
furi_record_close(RECORD_STORAGE);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
flipper_format_free(file);
|
|
flipper_format_free(file);
|
|
@@ -642,8 +724,8 @@ static QRCodeApp* qrcode_app_alloc() {
|
|
|
* @param qrcode_app The app to free
|
|
* @param qrcode_app The app to free
|
|
|
*/
|
|
*/
|
|
|
static void qrcode_app_free(QRCodeApp* instance) {
|
|
static void qrcode_app_free(QRCodeApp* instance) {
|
|
|
- if (instance->message) furi_string_free(instance->message);
|
|
|
|
|
- if (instance->qrcode) qrcode_free(instance->qrcode);
|
|
|
|
|
|
|
+ if(instance->message) furi_string_free(instance->message);
|
|
|
|
|
+ if(instance->qrcode) qrcode_free(instance->qrcode);
|
|
|
|
|
|
|
|
gui_remove_view_port(instance->gui, instance->view_port);
|
|
gui_remove_view_port(instance->gui, instance->view_port);
|
|
|
furi_record_close(RECORD_GUI);
|
|
furi_record_close(RECORD_GUI);
|
|
@@ -663,14 +745,14 @@ int32_t qrcode_app(void* p) {
|
|
|
FuriString* file_path = furi_string_alloc();
|
|
FuriString* file_path = furi_string_alloc();
|
|
|
|
|
|
|
|
do {
|
|
do {
|
|
|
- if (p && strlen(p)) {
|
|
|
|
|
|
|
+ if(p && strlen(p)) {
|
|
|
furi_string_set(file_path, (const char*)p);
|
|
furi_string_set(file_path, (const char*)p);
|
|
|
} else {
|
|
} else {
|
|
|
furi_string_set(file_path, QRCODE_FOLDER);
|
|
furi_string_set(file_path, QRCODE_FOLDER);
|
|
|
|
|
|
|
|
DialogsFileBrowserOptions browser_options;
|
|
DialogsFileBrowserOptions browser_options;
|
|
|
dialog_file_browser_set_basic_options(
|
|
dialog_file_browser_set_basic_options(
|
|
|
- &browser_options, QRCODE_EXTENSION, &I_qrcode_10px);
|
|
|
|
|
|
|
+ &browser_options, QRCODE_EXTENSION, &I_qrcode_10px);
|
|
|
browser_options.hide_ext = true;
|
|
browser_options.hide_ext = true;
|
|
|
browser_options.base_path = QRCODE_FOLDER;
|
|
browser_options.base_path = QRCODE_FOLDER;
|
|
|
|
|
|
|
@@ -678,26 +760,27 @@ int32_t qrcode_app(void* p) {
|
|
|
bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options);
|
|
bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options);
|
|
|
|
|
|
|
|
furi_record_close(RECORD_DIALOGS);
|
|
furi_record_close(RECORD_DIALOGS);
|
|
|
- if (!res) {
|
|
|
|
|
|
|
+ if(!res) {
|
|
|
FURI_LOG_E(TAG, "No file selected");
|
|
FURI_LOG_E(TAG, "No file selected");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!qrcode_load_file(instance, furi_string_get_cstr(file_path))) {
|
|
|
|
|
|
|
+ if(!qrcode_load_file(instance, furi_string_get_cstr(file_path))) {
|
|
|
FURI_LOG_E(TAG, "Unable to load file");
|
|
FURI_LOG_E(TAG, "Unable to load file");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
InputEvent input;
|
|
InputEvent input;
|
|
|
- while (furi_message_queue_get(instance->input_queue, &input, FuriWaitForever) == FuriStatusOk) {
|
|
|
|
|
|
|
+ while(furi_message_queue_get(instance->input_queue, &input, FuriWaitForever) ==
|
|
|
|
|
+ FuriStatusOk) {
|
|
|
furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk);
|
|
furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
- if (input.key == InputKeyBack) {
|
|
|
|
|
- if (instance->message) {
|
|
|
|
|
|
|
+ if(input.key == InputKeyBack) {
|
|
|
|
|
+ if(instance->message) {
|
|
|
furi_string_free(instance->message);
|
|
furi_string_free(instance->message);
|
|
|
instance->message = NULL;
|
|
instance->message = NULL;
|
|
|
}
|
|
}
|
|
|
- if (instance->qrcode) {
|
|
|
|
|
|
|
+ if(instance->qrcode) {
|
|
|
qrcode_free(instance->qrcode);
|
|
qrcode_free(instance->qrcode);
|
|
|
instance->qrcode = NULL;
|
|
instance->qrcode = NULL;
|
|
|
}
|
|
}
|
|
@@ -705,58 +788,70 @@ int32_t qrcode_app(void* p) {
|
|
|
instance->edit = false;
|
|
instance->edit = false;
|
|
|
furi_mutex_release(instance->mutex);
|
|
furi_mutex_release(instance->mutex);
|
|
|
break;
|
|
break;
|
|
|
- } else if (input.key == InputKeyRight) {
|
|
|
|
|
|
|
+ } else if(input.key == InputKeyRight) {
|
|
|
instance->show_stats = true;
|
|
instance->show_stats = true;
|
|
|
- } else if (input.key == InputKeyLeft) {
|
|
|
|
|
|
|
+ } else if(input.key == InputKeyLeft) {
|
|
|
instance->show_stats = false;
|
|
instance->show_stats = false;
|
|
|
- } else if (instance->show_stats && !instance->loading && instance->qrcode) {
|
|
|
|
|
- if (input.key == InputKeyUp) {
|
|
|
|
|
- if (!instance->edit) {
|
|
|
|
|
|
|
+ } else if(instance->show_stats && !instance->loading && instance->qrcode) {
|
|
|
|
|
+ if(input.key == InputKeyUp) {
|
|
|
|
|
+ if(!instance->edit) {
|
|
|
instance->selected_idx = MAX(0, instance->selected_idx - 1);
|
|
instance->selected_idx = MAX(0, instance->selected_idx - 1);
|
|
|
} else {
|
|
} else {
|
|
|
- if (instance->selected_idx == 0 && instance->set_mode < instance->max_mode) {
|
|
|
|
|
|
|
+ if(instance->selected_idx == 0 &&
|
|
|
|
|
+ instance->set_mode < instance->max_mode) {
|
|
|
instance->set_mode++;
|
|
instance->set_mode++;
|
|
|
- } else if (instance->selected_idx == 1 && instance->set_version < MAX_QRCODE_VERSION) {
|
|
|
|
|
|
|
+ } else if(
|
|
|
|
|
+ instance->selected_idx == 1 &&
|
|
|
|
|
+ instance->set_version < MAX_QRCODE_VERSION) {
|
|
|
instance->set_version++;
|
|
instance->set_version++;
|
|
|
- } else if (instance->selected_idx == 2) {
|
|
|
|
|
- uint8_t max_ecc = instance->set_version == instance->min_version ? instance->max_ecc_at_min_version : ECC_HIGH;
|
|
|
|
|
- if (instance->set_ecc < max_ecc) {
|
|
|
|
|
|
|
+ } else if(instance->selected_idx == 2) {
|
|
|
|
|
+ uint8_t max_ecc = instance->set_version == instance->min_version ?
|
|
|
|
|
+ instance->max_ecc_at_min_version :
|
|
|
|
|
+ ECC_HIGH;
|
|
|
|
|
+ if(instance->set_ecc < max_ecc) {
|
|
|
instance->set_ecc++;
|
|
instance->set_ecc++;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- } else if (input.key == InputKeyDown) {
|
|
|
|
|
- if (!instance->edit) {
|
|
|
|
|
|
|
+ } else if(input.key == InputKeyDown) {
|
|
|
|
|
+ if(!instance->edit) {
|
|
|
instance->selected_idx = MIN(2, instance->selected_idx + 1);
|
|
instance->selected_idx = MIN(2, instance->selected_idx + 1);
|
|
|
} else {
|
|
} else {
|
|
|
- if (instance->selected_idx == 0 && instance->set_mode > instance->min_mode) {
|
|
|
|
|
|
|
+ if(instance->selected_idx == 0 &&
|
|
|
|
|
+ instance->set_mode > instance->min_mode) {
|
|
|
instance->set_mode--;
|
|
instance->set_mode--;
|
|
|
- } else if (instance->selected_idx == 1 && instance->set_version > instance->min_version) {
|
|
|
|
|
|
|
+ } else if(
|
|
|
|
|
+ instance->selected_idx == 1 &&
|
|
|
|
|
+ instance->set_version > instance->min_version) {
|
|
|
instance->set_version--;
|
|
instance->set_version--;
|
|
|
- if (instance->set_version == instance->min_version) {
|
|
|
|
|
- instance->set_ecc = MIN(instance->set_ecc, instance->max_ecc_at_min_version);
|
|
|
|
|
|
|
+ if(instance->set_version == instance->min_version) {
|
|
|
|
|
+ instance->set_ecc =
|
|
|
|
|
+ MIN(instance->set_ecc, instance->max_ecc_at_min_version);
|
|
|
}
|
|
}
|
|
|
- } else if (instance->selected_idx == 2 && instance->set_ecc > 0) {
|
|
|
|
|
|
|
+ } else if(instance->selected_idx == 2 && instance->set_ecc > 0) {
|
|
|
instance->set_ecc--;
|
|
instance->set_ecc--;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- } else if (input.key == InputKeyOk) {
|
|
|
|
|
- if (
|
|
|
|
|
- instance->edit
|
|
|
|
|
- && (instance->set_mode != instance->qrcode->mode
|
|
|
|
|
- || instance->set_version != instance->qrcode->version
|
|
|
|
|
- || instance->set_ecc != instance->qrcode->ecc)) {
|
|
|
|
|
|
|
+ } else if(input.key == InputKeyOk) {
|
|
|
|
|
+ if(instance->edit && (instance->set_mode != instance->qrcode->mode ||
|
|
|
|
|
+ instance->set_version != instance->qrcode->version ||
|
|
|
|
|
+ instance->set_ecc != instance->qrcode->ecc)) {
|
|
|
uint8_t orig_min_version = instance->min_version;
|
|
uint8_t orig_min_version = instance->min_version;
|
|
|
uint8_t orig_max_ecc_at_min_version = instance->max_ecc_at_min_version;
|
|
uint8_t orig_max_ecc_at_min_version = instance->max_ecc_at_min_version;
|
|
|
- if (instance->set_mode != instance->qrcode->mode) {
|
|
|
|
|
|
|
+ if(instance->set_mode != instance->qrcode->mode) {
|
|
|
uint16_t len = (uint16_t)furi_string_size(instance->message);
|
|
uint16_t len = (uint16_t)furi_string_size(instance->message);
|
|
|
uint8_t min_version = 0;
|
|
uint8_t min_version = 0;
|
|
|
uint8_t max_ecc_at_min_version = 0;
|
|
uint8_t max_ecc_at_min_version = 0;
|
|
|
- if (find_min_version_max_ecc(len, instance->set_mode, &min_version, &max_ecc_at_min_version)) {
|
|
|
|
|
- if (instance->set_version < min_version) {
|
|
|
|
|
|
|
+ if(find_min_version_max_ecc(
|
|
|
|
|
+ len,
|
|
|
|
|
+ instance->set_mode,
|
|
|
|
|
+ &min_version,
|
|
|
|
|
+ &max_ecc_at_min_version)) {
|
|
|
|
|
+ if(instance->set_version < min_version) {
|
|
|
instance->set_version = min_version;
|
|
instance->set_version = min_version;
|
|
|
}
|
|
}
|
|
|
- if (instance->set_version == min_version && instance->set_ecc > max_ecc_at_min_version) {
|
|
|
|
|
|
|
+ if(instance->set_version == min_version &&
|
|
|
|
|
+ instance->set_ecc > max_ecc_at_min_version) {
|
|
|
instance->set_ecc = max_ecc_at_min_version;
|
|
instance->set_ecc = max_ecc_at_min_version;
|
|
|
}
|
|
}
|
|
|
instance->min_version = min_version;
|
|
instance->min_version = min_version;
|
|
@@ -769,7 +864,11 @@ int32_t qrcode_app(void* p) {
|
|
|
QRCode* qrcode = instance->qrcode;
|
|
QRCode* qrcode = instance->qrcode;
|
|
|
instance->loading = true;
|
|
instance->loading = true;
|
|
|
|
|
|
|
|
- if (rebuild_qrcode(instance, instance->set_mode, instance->set_version, instance->set_ecc)) {
|
|
|
|
|
|
|
+ if(rebuild_qrcode(
|
|
|
|
|
+ instance,
|
|
|
|
|
+ instance->set_mode,
|
|
|
|
|
+ instance->set_version,
|
|
|
|
|
+ instance->set_ecc)) {
|
|
|
qrcode_free(qrcode);
|
|
qrcode_free(qrcode);
|
|
|
} else {
|
|
} else {
|
|
|
FURI_LOG_E(TAG, "Could not rebuild qrcode");
|
|
FURI_LOG_E(TAG, "Could not rebuild qrcode");
|
|
@@ -791,12 +890,12 @@ int32_t qrcode_app(void* p) {
|
|
|
view_port_update(instance->view_port);
|
|
view_port_update(instance->view_port);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (p && strlen(p)) {
|
|
|
|
|
|
|
+ if(p && strlen(p)) {
|
|
|
// if started with an arg, exit instead
|
|
// if started with an arg, exit instead
|
|
|
// of looping back to the browser
|
|
// of looping back to the browser
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- } while (true);
|
|
|
|
|
|
|
+ } while(true);
|
|
|
|
|
|
|
|
furi_string_free(file_path);
|
|
furi_string_free(file_path);
|
|
|
qrcode_app_free(instance);
|
|
qrcode_app_free(instance);
|