mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-08 23:08:10 -07:00
Merge remote-tracking branch 'upstream/dev' into mrtd
This commit is contained in:
@@ -57,11 +57,26 @@ static ELFSection* elf_file_get_section(ELFFile* elf, const char* name) {
|
||||
return ELFSectionDict_get(elf->sections, name);
|
||||
}
|
||||
|
||||
static void elf_file_put_section(ELFFile* elf, const char* name, ELFSection* section) {
|
||||
ELFSectionDict_set_at(elf->sections, strdup(name), *section);
|
||||
static ELFSection* elf_file_get_or_put_section(ELFFile* elf, const char* name) {
|
||||
ELFSection* section_p = elf_file_get_section(elf, name);
|
||||
if(!section_p) {
|
||||
ELFSectionDict_set_at(
|
||||
elf->sections,
|
||||
strdup(name),
|
||||
(ELFSection){
|
||||
.data = NULL,
|
||||
.sec_idx = 0,
|
||||
.size = 0,
|
||||
.rel_count = 0,
|
||||
.rel_offset = 0,
|
||||
});
|
||||
section_p = elf_file_get_section(elf, name);
|
||||
}
|
||||
|
||||
return section_p;
|
||||
}
|
||||
|
||||
static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t name) {
|
||||
static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, FuriString* name) {
|
||||
bool result = false;
|
||||
|
||||
off_t old = storage_file_tell(elf->fd);
|
||||
@@ -74,7 +89,7 @@ static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t nam
|
||||
|
||||
while(true) {
|
||||
uint16_t read = storage_file_read(elf->fd, buffer, ELF_NAME_BUFFER_LEN);
|
||||
string_cat_str(name, buffer);
|
||||
furi_string_cat(name, buffer);
|
||||
if(strlen(buffer) < ELF_NAME_BUFFER_LEN) {
|
||||
result = true;
|
||||
break;
|
||||
@@ -89,11 +104,11 @@ static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t nam
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool elf_read_section_name(ELFFile* elf, off_t offset, string_t name) {
|
||||
static bool elf_read_section_name(ELFFile* elf, off_t offset, FuriString* name) {
|
||||
return elf_read_string_from_offset(elf, elf->section_table_strings + offset, name);
|
||||
}
|
||||
|
||||
static bool elf_read_symbol_name(ELFFile* elf, off_t offset, string_t name) {
|
||||
static bool elf_read_symbol_name(ELFFile* elf, off_t offset, FuriString* name) {
|
||||
return elf_read_string_from_offset(elf, elf->symbol_table_strings + offset, name);
|
||||
}
|
||||
|
||||
@@ -103,8 +118,11 @@ static bool elf_read_section_header(ELFFile* elf, size_t section_idx, Elf32_Shdr
|
||||
storage_file_read(elf->fd, section_header, sizeof(Elf32_Shdr)) == sizeof(Elf32_Shdr);
|
||||
}
|
||||
|
||||
static bool
|
||||
elf_read_section(ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header, string_t name) {
|
||||
static bool elf_read_section(
|
||||
ELFFile* elf,
|
||||
size_t section_idx,
|
||||
Elf32_Shdr* section_header,
|
||||
FuriString* name) {
|
||||
if(!elf_read_section_header(elf, section_idx, section_header)) {
|
||||
return false;
|
||||
}
|
||||
@@ -116,7 +134,7 @@ static bool
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, string_t name) {
|
||||
static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, FuriString* name) {
|
||||
bool success = false;
|
||||
off_t old = storage_file_tell(elf->fd);
|
||||
off_t pos = elf->symbol_table + n * sizeof(Elf32_Sym);
|
||||
@@ -276,19 +294,17 @@ static void elf_relocate_mov(Elf32_Addr relAddr, int type, Elf32_Addr symAddr) {
|
||||
int32_t addend = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; /* imm16 */
|
||||
|
||||
uint32_t addr = (symAddr + addend);
|
||||
if (type == R_ARM_THM_MOVT_ABS) {
|
||||
if(type == R_ARM_THM_MOVT_ABS) {
|
||||
addr >>= 16; /* upper 16 bits */
|
||||
} else {
|
||||
addr &= 0x0000FFFF; /* lower 16 bits */
|
||||
}
|
||||
|
||||
/* Re-encode */
|
||||
((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0)
|
||||
| (((addr >> 11) & 1) << 10) /* i */
|
||||
| ((addr >> 12) & 0x000F); /* imm4 */
|
||||
((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00)
|
||||
| (((addr >> 8) & 0x7) << 12) /* imm3 */
|
||||
| (addr & 0x00FF); /* imm8 */
|
||||
((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0) | (((addr >> 11) & 1) << 10) /* i */
|
||||
| ((addr >> 12) & 0x000F); /* imm4 */
|
||||
((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00) | (((addr >> 8) & 0x7) << 12) /* imm3 */
|
||||
| (addr & 0x00FF); /* imm8 */
|
||||
}
|
||||
|
||||
static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf32_Addr symAddr) {
|
||||
@@ -307,7 +323,10 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3
|
||||
case R_ARM_THM_MOVW_ABS_NC:
|
||||
case R_ARM_THM_MOVT_ABS:
|
||||
elf_relocate_mov(relAddr, type, symAddr);
|
||||
FURI_LOG_D(TAG, " R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
" R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X",
|
||||
(unsigned int)*((uint32_t*)relAddr));
|
||||
break;
|
||||
default:
|
||||
FURI_LOG_E(TAG, " Undefined relocation %d", type);
|
||||
@@ -316,17 +335,17 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
|
||||
static bool elf_relocate(ELFFile* elf, ELFSection* s) {
|
||||
if(s->data) {
|
||||
Elf32_Rel rel;
|
||||
size_t relEntries = h->sh_size / sizeof(rel);
|
||||
size_t relEntries = s->rel_count;
|
||||
size_t relCount;
|
||||
(void)storage_file_seek(elf->fd, h->sh_offset, true);
|
||||
(void)storage_file_seek(elf->fd, s->rel_offset, true);
|
||||
FURI_LOG_D(TAG, " Offset Info Type Name");
|
||||
|
||||
int relocate_result = true;
|
||||
string_t symbol_name;
|
||||
string_init(symbol_name);
|
||||
FuriString* symbol_name;
|
||||
symbol_name = furi_string_alloc();
|
||||
|
||||
for(relCount = 0; relCount < relEntries; relCount++) {
|
||||
if(relCount % RESOLVER_THREAD_YIELD_STEP == 0) {
|
||||
@@ -336,7 +355,7 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
|
||||
|
||||
if(storage_file_read(elf->fd, &rel, sizeof(Elf32_Rel)) != sizeof(Elf32_Rel)) {
|
||||
FURI_LOG_E(TAG, " reloc read fail");
|
||||
string_clear(symbol_name);
|
||||
furi_string_free(symbol_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -348,10 +367,10 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
|
||||
|
||||
if(!address_cache_get(elf->relocation_cache, symEntry, &symAddr)) {
|
||||
Elf32_Sym sym;
|
||||
string_reset(symbol_name);
|
||||
furi_string_reset(symbol_name);
|
||||
if(!elf_read_symbol(elf, symEntry, &sym, symbol_name)) {
|
||||
FURI_LOG_E(TAG, " symbol read fail");
|
||||
string_clear(symbol_name);
|
||||
furi_string_free(symbol_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -361,9 +380,9 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
|
||||
(unsigned int)rel.r_offset,
|
||||
(unsigned int)rel.r_info,
|
||||
elf_reloc_type_to_str(relType),
|
||||
string_get_cstr(symbol_name));
|
||||
furi_string_get_cstr(symbol_name));
|
||||
|
||||
symAddr = elf_address_of(elf, &sym, string_get_cstr(symbol_name));
|
||||
symAddr = elf_address_of(elf, &sym, furi_string_get_cstr(symbol_name));
|
||||
address_cache_put(elf->relocation_cache, symEntry, symAddr);
|
||||
}
|
||||
|
||||
@@ -377,11 +396,11 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
|
||||
relocate_result = false;
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_E(TAG, " No symbol address of %s", string_get_cstr(symbol_name));
|
||||
FURI_LOG_E(TAG, " No symbol address of %s", furi_string_get_cstr(symbol_name));
|
||||
relocate_result = false;
|
||||
}
|
||||
}
|
||||
string_clear(symbol_name);
|
||||
furi_string_free(symbol_name);
|
||||
|
||||
return relocate_result;
|
||||
} else {
|
||||
@@ -391,14 +410,6 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/********************************************* MISC ***********************************************/
|
||||
/**************************************************************************************************/
|
||||
|
||||
static bool cstr_prefix(const char* prefix, const char* string) {
|
||||
return strncmp(prefix, string, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/************************************ Internal FAP interfaces *************************************/
|
||||
/**************************************************************************************************/
|
||||
@@ -441,81 +452,137 @@ static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) {
|
||||
section_header->sh_size;
|
||||
}
|
||||
|
||||
static bool str_prefix(const char* str, const char* prefix) {
|
||||
return strncmp(prefix, str, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
static bool elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) {
|
||||
if(section_header->sh_size == 0) {
|
||||
FURI_LOG_D(TAG, "No data for section");
|
||||
return true;
|
||||
}
|
||||
|
||||
section->data = aligned_malloc(section_header->sh_size, section_header->sh_addralign);
|
||||
section->size = section_header->sh_size;
|
||||
|
||||
if(section_header->sh_type == SHT_NOBITS) {
|
||||
// BSS section, no data to load
|
||||
return true;
|
||||
}
|
||||
|
||||
if((!storage_file_seek(elf->fd, section_header->sh_offset, true)) ||
|
||||
(storage_file_read(elf->fd, section->data, section_header->sh_size) !=
|
||||
section_header->sh_size)) {
|
||||
FURI_LOG_E(TAG, " seek/read fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
FURI_LOG_D(TAG, "0x%X", section->data);
|
||||
return true;
|
||||
}
|
||||
|
||||
static SectionType elf_preload_section(
|
||||
ELFFile* elf,
|
||||
size_t section_idx,
|
||||
Elf32_Shdr* section_header,
|
||||
string_t name_string,
|
||||
FuriString* name_string,
|
||||
FlipperApplicationManifest* manifest) {
|
||||
const char* name = string_get_cstr(name_string);
|
||||
const char* name = furi_string_get_cstr(name_string);
|
||||
|
||||
const struct {
|
||||
const char* prefix;
|
||||
SectionType type;
|
||||
} lookup_sections[] = {
|
||||
{".text", SectionTypeData},
|
||||
{".rodata", SectionTypeData},
|
||||
{".data", SectionTypeData},
|
||||
{".bss", SectionTypeData},
|
||||
{".preinit_array", SectionTypeData},
|
||||
{".init_array", SectionTypeData},
|
||||
{".fini_array", SectionTypeData},
|
||||
{".rel.text", SectionTypeRelData},
|
||||
{".rel.rodata", SectionTypeRelData},
|
||||
{".rel.data", SectionTypeRelData},
|
||||
{".rel.preinit_array", SectionTypeRelData},
|
||||
{".rel.init_array", SectionTypeRelData},
|
||||
{".rel.fini_array", SectionTypeRelData},
|
||||
};
|
||||
#ifdef ELF_DEBUG_LOG
|
||||
// log section name, type and flags
|
||||
FuriString* flags_string = furi_string_alloc();
|
||||
if(section_header->sh_flags & SHF_WRITE) furi_string_cat(flags_string, "W");
|
||||
if(section_header->sh_flags & SHF_ALLOC) furi_string_cat(flags_string, "A");
|
||||
if(section_header->sh_flags & SHF_EXECINSTR) furi_string_cat(flags_string, "X");
|
||||
if(section_header->sh_flags & SHF_MERGE) furi_string_cat(flags_string, "M");
|
||||
if(section_header->sh_flags & SHF_STRINGS) furi_string_cat(flags_string, "S");
|
||||
if(section_header->sh_flags & SHF_INFO_LINK) furi_string_cat(flags_string, "I");
|
||||
if(section_header->sh_flags & SHF_LINK_ORDER) furi_string_cat(flags_string, "L");
|
||||
if(section_header->sh_flags & SHF_OS_NONCONFORMING) furi_string_cat(flags_string, "O");
|
||||
if(section_header->sh_flags & SHF_GROUP) furi_string_cat(flags_string, "G");
|
||||
if(section_header->sh_flags & SHF_TLS) furi_string_cat(flags_string, "T");
|
||||
if(section_header->sh_flags & SHF_COMPRESSED) furi_string_cat(flags_string, "T");
|
||||
if(section_header->sh_flags & SHF_MASKOS) furi_string_cat(flags_string, "o");
|
||||
if(section_header->sh_flags & SHF_MASKPROC) furi_string_cat(flags_string, "p");
|
||||
if(section_header->sh_flags & SHF_ORDERED) furi_string_cat(flags_string, "R");
|
||||
if(section_header->sh_flags & SHF_EXCLUDE) furi_string_cat(flags_string, "E");
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(lookup_sections); i++) {
|
||||
if(cstr_prefix(lookup_sections[i].prefix, name)) {
|
||||
FURI_LOG_D(TAG, "Found section %s", lookup_sections[i].prefix);
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Section %s: type: %ld, flags: %s",
|
||||
name,
|
||||
section_header->sh_type,
|
||||
furi_string_get_cstr(flags_string));
|
||||
furi_string_free(flags_string);
|
||||
#endif
|
||||
|
||||
if(lookup_sections[i].type == SectionTypeRelData) {
|
||||
name = name + strlen(".rel");
|
||||
}
|
||||
// ignore .ARM and .rel.ARM sections
|
||||
// TODO: how to do it not by name?
|
||||
// .ARM: type 0x70000001, flags SHF_ALLOC | SHF_LINK_ORDER
|
||||
// .rel.ARM: type 0x9, flags SHT_REL
|
||||
if(str_prefix(name, ".ARM.") || str_prefix(name, ".rel.ARM.")) {
|
||||
FURI_LOG_D(TAG, "Ignoring ARM section");
|
||||
return SectionTypeUnused;
|
||||
}
|
||||
|
||||
ELFSection* section_p = elf_file_get_section(elf, name);
|
||||
if(!section_p) {
|
||||
ELFSection section = {
|
||||
.data = NULL,
|
||||
.sec_idx = 0,
|
||||
.rel_sec_idx = 0,
|
||||
.size = 0,
|
||||
};
|
||||
// Load allocable section
|
||||
if(section_header->sh_flags & SHF_ALLOC) {
|
||||
ELFSection* section_p = elf_file_get_or_put_section(elf, name);
|
||||
section_p->sec_idx = section_idx;
|
||||
|
||||
elf_file_put_section(elf, name, §ion);
|
||||
section_p = elf_file_get_section(elf, name);
|
||||
}
|
||||
if(section_header->sh_type == SHT_PREINIT_ARRAY) {
|
||||
elf->preinit_array = section_p;
|
||||
} else if(section_header->sh_type == SHT_INIT_ARRAY) {
|
||||
elf->init_array = section_p;
|
||||
} else if(section_header->sh_type == SHT_FINI_ARRAY) {
|
||||
elf->fini_array = section_p;
|
||||
}
|
||||
|
||||
if(lookup_sections[i].type == SectionTypeRelData) {
|
||||
section_p->rel_sec_idx = section_idx;
|
||||
} else {
|
||||
section_p->sec_idx = section_idx;
|
||||
}
|
||||
|
||||
return lookup_sections[i].type;
|
||||
if(!elf_load_section_data(elf, section_p, section_header)) {
|
||||
FURI_LOG_E(TAG, "Error loading section '%s'", name);
|
||||
return SectionTypeERROR;
|
||||
} else {
|
||||
return SectionTypeData;
|
||||
}
|
||||
}
|
||||
|
||||
// Load link info section
|
||||
if(section_header->sh_flags & SHF_INFO_LINK) {
|
||||
name = name + strlen(".rel");
|
||||
ELFSection* section_p = elf_file_get_or_put_section(elf, name);
|
||||
section_p->rel_count = section_header->sh_size / sizeof(Elf32_Rel);
|
||||
section_p->rel_offset = section_header->sh_offset;
|
||||
return SectionTypeRelData;
|
||||
}
|
||||
|
||||
// Load symbol table
|
||||
if(strcmp(name, ".symtab") == 0) {
|
||||
FURI_LOG_D(TAG, "Found .symtab section");
|
||||
elf->symbol_table = section_header->sh_offset;
|
||||
elf->symbol_count = section_header->sh_size / sizeof(Elf32_Sym);
|
||||
return SectionTypeSymTab;
|
||||
} else if(strcmp(name, ".strtab") == 0) {
|
||||
}
|
||||
|
||||
// Load string table
|
||||
if(strcmp(name, ".strtab") == 0) {
|
||||
FURI_LOG_D(TAG, "Found .strtab section");
|
||||
elf->symbol_table_strings = section_header->sh_offset;
|
||||
return SectionTypeStrTab;
|
||||
} else if(strcmp(name, ".fapmeta") == 0) {
|
||||
}
|
||||
|
||||
// Load manifest section
|
||||
if(strcmp(name, ".fapmeta") == 0) {
|
||||
FURI_LOG_D(TAG, "Found .fapmeta section");
|
||||
if(elf_load_metadata(elf, section_header, manifest)) {
|
||||
return SectionTypeManifest;
|
||||
} else {
|
||||
return SectionTypeERROR;
|
||||
}
|
||||
} else if(strcmp(name, ".gnu_debuglink") == 0) {
|
||||
}
|
||||
|
||||
// Load debug link section
|
||||
if(strcmp(name, ".gnu_debuglink") == 0) {
|
||||
FURI_LOG_D(TAG, "Found .gnu_debuglink section");
|
||||
if(elf_load_debug_link(elf, section_header)) {
|
||||
return SectionTypeDebugLink;
|
||||
@@ -527,61 +594,17 @@ static SectionType elf_preload_section(
|
||||
return SectionTypeUnused;
|
||||
}
|
||||
|
||||
static bool elf_load_section_data(ELFFile* elf, ELFSection* section) {
|
||||
Elf32_Shdr section_header;
|
||||
if(section->sec_idx == 0) {
|
||||
FURI_LOG_D(TAG, "Section is not present");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!elf_read_section_header(elf, section->sec_idx, §ion_header)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(section_header.sh_size == 0) {
|
||||
FURI_LOG_D(TAG, "No data for section");
|
||||
return true;
|
||||
}
|
||||
|
||||
section->data = aligned_malloc(section_header.sh_size, section_header.sh_addralign);
|
||||
section->size = section_header.sh_size;
|
||||
|
||||
if(section_header.sh_type == SHT_NOBITS) {
|
||||
/* section is empty (.bss?) */
|
||||
/* no need to memset - allocator already did that */
|
||||
return true;
|
||||
}
|
||||
|
||||
if((!storage_file_seek(elf->fd, section_header.sh_offset, true)) ||
|
||||
(storage_file_read(elf->fd, section->data, section_header.sh_size) !=
|
||||
section_header.sh_size)) {
|
||||
FURI_LOG_E(TAG, " seek/read fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
FURI_LOG_D(TAG, "0x%X", section->data);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool elf_relocate_section(ELFFile* elf, ELFSection* section) {
|
||||
Elf32_Shdr section_header;
|
||||
if(section->rel_sec_idx) {
|
||||
if(section->rel_count) {
|
||||
FURI_LOG_D(TAG, "Relocating section");
|
||||
if(elf_read_section_header(elf, section->rel_sec_idx, §ion_header))
|
||||
return elf_relocate(elf, §ion_header, section);
|
||||
else {
|
||||
FURI_LOG_E(TAG, "Error reading section header");
|
||||
return false;
|
||||
}
|
||||
return elf_relocate(elf, section);
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "No relocation index"); /* Not an error */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void elf_file_call_section_list(ELFFile* elf, const char* name, bool reverse_order) {
|
||||
ELFSection* section = elf_file_get_section(elf, name);
|
||||
|
||||
static void elf_file_call_section_list(ELFSection* section, bool reverse_order) {
|
||||
if(section && section->size) {
|
||||
const uint32_t* start = section->data;
|
||||
const uint32_t* end = section->data + section->size;
|
||||
@@ -670,19 +693,19 @@ bool elf_file_open(ELFFile* elf, const char* path) {
|
||||
|
||||
bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest) {
|
||||
bool result = false;
|
||||
string_t name;
|
||||
string_init(name);
|
||||
FuriString* name;
|
||||
name = furi_string_alloc();
|
||||
|
||||
FURI_LOG_D(TAG, "Looking for manifest section");
|
||||
for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
|
||||
Elf32_Shdr section_header;
|
||||
|
||||
string_reset(name);
|
||||
furi_string_reset(name);
|
||||
if(!elf_read_section(elf, section_idx, §ion_header, name)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(string_cmp(name, ".fapmeta") == 0) {
|
||||
if(furi_string_cmp(name, ".fapmeta") == 0) {
|
||||
if(elf_load_metadata(elf, §ion_header, manifest)) {
|
||||
FURI_LOG_D(TAG, "Load manifest done");
|
||||
result = true;
|
||||
@@ -693,26 +716,27 @@ bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest)
|
||||
}
|
||||
}
|
||||
|
||||
string_clear(name);
|
||||
furi_string_free(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manifest) {
|
||||
SectionType loaded_sections = SectionTypeERROR;
|
||||
string_t name;
|
||||
string_init(name);
|
||||
FuriString* name;
|
||||
name = furi_string_alloc();
|
||||
|
||||
FURI_LOG_D(TAG, "Scan ELF indexs...");
|
||||
for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
|
||||
Elf32_Shdr section_header;
|
||||
|
||||
string_reset(name);
|
||||
furi_string_reset(name);
|
||||
if(!elf_read_section(elf, section_idx, §ion_header, name)) {
|
||||
loaded_sections = SectionTypeERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
FURI_LOG_D(TAG, "Preloading data for section #%d %s", section_idx, string_get_cstr(name));
|
||||
FURI_LOG_D(
|
||||
TAG, "Preloading data for section #%d %s", section_idx, furi_string_get_cstr(name));
|
||||
SectionType section_type =
|
||||
elf_preload_section(elf, section_idx, §ion_header, name, manifest);
|
||||
loaded_sections |= section_type;
|
||||
@@ -723,8 +747,7 @@ bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manif
|
||||
}
|
||||
}
|
||||
|
||||
string_clear(name);
|
||||
FURI_LOG_D(TAG, "Load symbols done");
|
||||
furi_string_free(name);
|
||||
|
||||
return IS_FLAGS_SET(loaded_sections, SectionTypeValid);
|
||||
}
|
||||
@@ -734,16 +757,6 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) {
|
||||
ELFSectionDict_it_t it;
|
||||
|
||||
AddressCache_init(elf->relocation_cache);
|
||||
size_t start = furi_get_tick();
|
||||
|
||||
for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); ELFSectionDict_next(it)) {
|
||||
ELFSectionDict_itref_t* itref = ELFSectionDict_ref(it);
|
||||
FURI_LOG_D(TAG, "Loading section '%s'", itref->key);
|
||||
if(!elf_load_section_data(elf, &itref->value)) {
|
||||
FURI_LOG_E(TAG, "Error loading section '%s'", itref->key);
|
||||
status = ELFFileLoadStatusUnspecifiedError;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == ELFFileLoadStatusSuccess) {
|
||||
for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it);
|
||||
@@ -772,14 +785,13 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) {
|
||||
FURI_LOG_D(TAG, "Relocation cache size: %u", AddressCache_size(elf->relocation_cache));
|
||||
FURI_LOG_D(TAG, "Trampoline cache size: %u", AddressCache_size(elf->trampoline_cache));
|
||||
AddressCache_clear(elf->relocation_cache);
|
||||
FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void elf_file_pre_run(ELFFile* elf) {
|
||||
elf_file_call_section_list(elf, ".preinit_array", false);
|
||||
elf_file_call_section_list(elf, ".init_array", false);
|
||||
elf_file_call_section_list(elf->preinit_array, false);
|
||||
elf_file_call_section_list(elf->init_array, false);
|
||||
}
|
||||
|
||||
int32_t elf_file_run(ELFFile* elf, void* args) {
|
||||
@@ -789,7 +801,7 @@ int32_t elf_file_run(ELFFile* elf, void* args) {
|
||||
}
|
||||
|
||||
void elf_file_post_run(ELFFile* elf) {
|
||||
elf_file_call_section_list(elf, ".fini_array", true);
|
||||
elf_file_call_section_list(elf->fini_array, true);
|
||||
}
|
||||
|
||||
const ElfApiInterface* elf_file_get_api_interface(ELFFile* elf_file) {
|
||||
|
||||
@@ -16,8 +16,10 @@ typedef int32_t(entry_t)(void*);
|
||||
typedef struct {
|
||||
void* data;
|
||||
uint16_t sec_idx;
|
||||
uint16_t rel_sec_idx;
|
||||
Elf32_Word size;
|
||||
|
||||
size_t rel_count;
|
||||
Elf32_Off rel_offset;
|
||||
} ELFSection;
|
||||
|
||||
DICT_DEF2(ELFSectionDict, const char*, M_CSTR_OPLIST, ELFSection, M_POD_OPLIST)
|
||||
@@ -39,6 +41,10 @@ struct ELFFile {
|
||||
File* fd;
|
||||
const ElfApiInterface* api_interface;
|
||||
ELFDebugLinkInfo debug_link_info;
|
||||
|
||||
ELFSection* preinit_array;
|
||||
ELFSection* init_array;
|
||||
ELFSection* fini_array;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -137,7 +137,7 @@ bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key) {
|
||||
|
||||
bool flipper_format_read_header(
|
||||
FlipperFormat* flipper_format,
|
||||
string_t filetype,
|
||||
FuriString* filetype,
|
||||
uint32_t* version) {
|
||||
furi_assert(flipper_format);
|
||||
return flipper_format_read_string(flipper_format, flipper_format_filetype_key, filetype) &&
|
||||
@@ -146,10 +146,11 @@ bool flipper_format_read_header(
|
||||
|
||||
bool flipper_format_write_header(
|
||||
FlipperFormat* flipper_format,
|
||||
string_t filetype,
|
||||
FuriString* filetype,
|
||||
const uint32_t version) {
|
||||
furi_assert(flipper_format);
|
||||
return flipper_format_write_header_cstr(flipper_format, string_get_cstr(filetype), version);
|
||||
return flipper_format_write_header_cstr(
|
||||
flipper_format, furi_string_get_cstr(filetype), version);
|
||||
}
|
||||
|
||||
bool flipper_format_write_header_cstr(
|
||||
@@ -171,18 +172,18 @@ bool flipper_format_get_value_count(
|
||||
flipper_format->stream, key, count, flipper_format->strict_mode);
|
||||
}
|
||||
|
||||
bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, string_t data) {
|
||||
bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data) {
|
||||
furi_assert(flipper_format);
|
||||
return flipper_format_stream_read_value_line(
|
||||
flipper_format->stream, key, FlipperStreamValueStr, data, 1, flipper_format->strict_mode);
|
||||
}
|
||||
|
||||
bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, string_t data) {
|
||||
bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data) {
|
||||
furi_assert(flipper_format);
|
||||
FlipperStreamWriteData write_data = {
|
||||
.key = key,
|
||||
.type = FlipperStreamValueStr,
|
||||
.data = string_get_cstr(data),
|
||||
.data = furi_string_get_cstr(data),
|
||||
.data_size = 1,
|
||||
};
|
||||
bool result = flipper_format_stream_write_value_line(flipper_format->stream, &write_data);
|
||||
@@ -386,9 +387,9 @@ bool flipper_format_write_hex(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool flipper_format_write_comment(FlipperFormat* flipper_format, string_t data) {
|
||||
bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data) {
|
||||
furi_assert(flipper_format);
|
||||
return flipper_format_write_comment_cstr(flipper_format, string_get_cstr(data));
|
||||
return flipper_format_write_comment_cstr(flipper_format, furi_string_get_cstr(data));
|
||||
}
|
||||
|
||||
bool flipper_format_write_comment_cstr(FlipperFormat* flipper_format, const char* data) {
|
||||
@@ -409,12 +410,12 @@ bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, string_t data) {
|
||||
bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data) {
|
||||
furi_assert(flipper_format);
|
||||
FlipperStreamWriteData write_data = {
|
||||
.key = key,
|
||||
.type = FlipperStreamValueStr,
|
||||
.data = string_get_cstr(data),
|
||||
.data = furi_string_get_cstr(data),
|
||||
.data_size = 1,
|
||||
};
|
||||
bool result = flipper_format_stream_delete_key_and_write(
|
||||
@@ -522,7 +523,7 @@ bool flipper_format_update_hex(
|
||||
bool flipper_format_insert_or_update_string(
|
||||
FlipperFormat* flipper_format,
|
||||
const char* key,
|
||||
string_t data) {
|
||||
FuriString* data) {
|
||||
bool result = false;
|
||||
|
||||
if(!flipper_format_key_exist(flipper_format, key)) {
|
||||
|
||||
@@ -70,13 +70,13 @@
|
||||
*
|
||||
* do {
|
||||
* uint32_t version = 1;
|
||||
* string_t file_type;
|
||||
* string_t string_value;
|
||||
* FuriString* file_type;
|
||||
* FuriString* string_value;
|
||||
* uint32_t uint32_value = 1;
|
||||
* uint16_t array_size = 4;
|
||||
* uint8_t* array[array_size] = {0};
|
||||
* string_init(file_type);
|
||||
* string_init(string_value);
|
||||
* file_type = furi_string_alloc();
|
||||
* string_value = furi_string_alloc();
|
||||
*
|
||||
* if(!flipper_format_file_open_existing(file, EXT_PATH("flipper_format_test"))) break;
|
||||
* if(!flipper_format_read_header(file, file_type, &version)) break;
|
||||
@@ -94,7 +94,6 @@
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <mlib/m-string.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -227,7 +226,7 @@ bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key);
|
||||
*/
|
||||
bool flipper_format_read_header(
|
||||
FlipperFormat* flipper_format,
|
||||
string_t filetype,
|
||||
FuriString* filetype,
|
||||
uint32_t* version);
|
||||
|
||||
/**
|
||||
@@ -239,7 +238,7 @@ bool flipper_format_read_header(
|
||||
*/
|
||||
bool flipper_format_write_header(
|
||||
FlipperFormat* flipper_format,
|
||||
string_t filetype,
|
||||
FuriString* filetype,
|
||||
const uint32_t version);
|
||||
|
||||
/**
|
||||
@@ -273,7 +272,7 @@ bool flipper_format_get_value_count(
|
||||
* @param data Value
|
||||
* @return True on success
|
||||
*/
|
||||
bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, string_t data);
|
||||
bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data);
|
||||
|
||||
/**
|
||||
* Write key and string
|
||||
@@ -282,7 +281,7 @@ bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key,
|
||||
* @param data Value
|
||||
* @return True on success
|
||||
*/
|
||||
bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, string_t data);
|
||||
bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data);
|
||||
|
||||
/**
|
||||
* Write key and string. Plain C string version.
|
||||
@@ -470,7 +469,7 @@ bool flipper_format_write_hex(
|
||||
* @param data Comment text
|
||||
* @return True on success
|
||||
*/
|
||||
bool flipper_format_write_comment(FlipperFormat* flipper_format, string_t data);
|
||||
bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data);
|
||||
|
||||
/**
|
||||
* Write comment. Plain C string version.
|
||||
@@ -495,7 +494,7 @@ bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key);
|
||||
* @param data Value
|
||||
* @return True on success
|
||||
*/
|
||||
bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, string_t data);
|
||||
bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data);
|
||||
|
||||
/**
|
||||
* Updates the value of the first matching key to a string value. Plain C version. Sets the RW pointer to a position at the end of inserted data.
|
||||
@@ -585,7 +584,7 @@ bool flipper_format_update_hex(
|
||||
bool flipper_format_insert_or_update_string(
|
||||
FlipperFormat* flipper_format,
|
||||
const char* key,
|
||||
string_t data);
|
||||
FuriString* data);
|
||||
|
||||
/**
|
||||
* Updates the value of the first matching key to a string value, or adds the key and value if the key did not exist.
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include "flipper_format_stream.h"
|
||||
#include "flipper_format_stream_i.h"
|
||||
|
||||
static inline bool flipper_format_stream_is_space(char c) {
|
||||
return c == ' ' || c == '\t' || c == flipper_format_eolr;
|
||||
}
|
||||
|
||||
static bool flipper_format_stream_write(Stream* stream, const void* data, size_t data_size) {
|
||||
size_t bytes_written = stream_write(stream, data, data_size);
|
||||
return bytes_written == data_size;
|
||||
@@ -26,8 +30,8 @@ bool flipper_format_stream_write_eol(Stream* stream) {
|
||||
return flipper_format_stream_write(stream, &flipper_format_eoln, 1);
|
||||
}
|
||||
|
||||
static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) {
|
||||
string_reset(key);
|
||||
static bool flipper_format_stream_read_valid_key(Stream* stream, FuriString* key) {
|
||||
furi_string_reset(key);
|
||||
const size_t buffer_size = 32;
|
||||
uint8_t buffer[buffer_size];
|
||||
|
||||
@@ -44,7 +48,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) {
|
||||
uint8_t data = buffer[i];
|
||||
if(data == flipper_format_eoln) {
|
||||
// EOL found, clean data, start accumulating data and set the new_line flag
|
||||
string_reset(key);
|
||||
furi_string_reset(key);
|
||||
accumulate = true;
|
||||
new_line = true;
|
||||
} else if(data == flipper_format_eolr) {
|
||||
@@ -60,7 +64,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) {
|
||||
// this can only be if we have previously found some kind of key, so
|
||||
// clear the data, set the flag that we no longer want to accumulate data
|
||||
// and reset the new_line flag
|
||||
string_reset(key);
|
||||
furi_string_reset(key);
|
||||
accumulate = false;
|
||||
new_line = false;
|
||||
} else {
|
||||
@@ -82,7 +86,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) {
|
||||
new_line = false;
|
||||
if(accumulate) {
|
||||
// and accumulate data if we want
|
||||
string_push_back(key, data);
|
||||
furi_string_push_back(key, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,13 +99,13 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) {
|
||||
|
||||
bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool strict_mode) {
|
||||
bool found = false;
|
||||
string_t read_key;
|
||||
FuriString* read_key;
|
||||
|
||||
string_init(read_key);
|
||||
read_key = furi_string_alloc();
|
||||
|
||||
while(!stream_eof(stream)) {
|
||||
if(flipper_format_stream_read_valid_key(stream, read_key)) {
|
||||
if(string_cmp_str(read_key, key) == 0) {
|
||||
if(furi_string_cmp_str(read_key, key) == 0) {
|
||||
if(!stream_seek(stream, 2, StreamOffsetFromCurrent)) break;
|
||||
|
||||
found = true;
|
||||
@@ -112,61 +116,70 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str
|
||||
}
|
||||
}
|
||||
}
|
||||
string_clear(read_key);
|
||||
furi_string_free(read_key);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool flipper_format_stream_read_value(Stream* stream, string_t value, bool* last) {
|
||||
string_reset(value);
|
||||
static bool flipper_format_stream_read_value(Stream* stream, FuriString* value, bool* last) {
|
||||
enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace;
|
||||
const size_t buffer_size = 32;
|
||||
uint8_t buffer[buffer_size];
|
||||
bool result = false;
|
||||
bool error = false;
|
||||
|
||||
furi_string_reset(value);
|
||||
|
||||
while(true) {
|
||||
size_t was_read = stream_read(stream, buffer, buffer_size);
|
||||
|
||||
if(was_read == 0) {
|
||||
// check EOF
|
||||
if(stream_eof(stream) && string_size(value) > 0) {
|
||||
if(state != LeadingSpace && stream_eof(stream)) {
|
||||
result = true;
|
||||
*last = true;
|
||||
break;
|
||||
} else {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < was_read; i++) {
|
||||
uint8_t data = buffer[i];
|
||||
if(data == flipper_format_eoln) {
|
||||
if(string_size(value) > 0) {
|
||||
if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
const uint8_t data = buffer[i];
|
||||
|
||||
result = true;
|
||||
*last = true;
|
||||
if(state == LeadingSpace) {
|
||||
if(flipper_format_stream_is_space(data)) {
|
||||
continue;
|
||||
} else if(data == flipper_format_eoln) {
|
||||
stream_seek(stream, i - was_read, StreamOffsetFromCurrent);
|
||||
error = true;
|
||||
break;
|
||||
} else {
|
||||
error = true;
|
||||
state = ReadValue;
|
||||
furi_string_push_back(value, data);
|
||||
}
|
||||
} else if(data == ' ') {
|
||||
if(string_size(value) > 0) {
|
||||
} else if(state == ReadValue) {
|
||||
if(flipper_format_stream_is_space(data)) {
|
||||
state = TrailingSpace;
|
||||
} else if(data == flipper_format_eoln) {
|
||||
if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
|
||||
error = true;
|
||||
break;
|
||||
} else {
|
||||
result = true;
|
||||
*last = true;
|
||||
}
|
||||
|
||||
result = true;
|
||||
*last = false;
|
||||
break;
|
||||
} else {
|
||||
furi_string_push_back(value, data);
|
||||
}
|
||||
|
||||
} else if(data == flipper_format_eolr) {
|
||||
// Ignore
|
||||
} else {
|
||||
string_push_back(value, data);
|
||||
} else if(state == TrailingSpace) {
|
||||
if(flipper_format_stream_is_space(data)) {
|
||||
continue;
|
||||
} else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
|
||||
error = true;
|
||||
} else {
|
||||
*last = (data == flipper_format_eoln);
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,8 +189,8 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) {
|
||||
string_reset(str_result);
|
||||
static bool flipper_format_stream_read_line(Stream* stream, FuriString* str_result) {
|
||||
furi_string_reset(str_result);
|
||||
const size_t buffer_size = 32;
|
||||
uint8_t buffer[buffer_size];
|
||||
|
||||
@@ -201,7 +214,7 @@ static bool flipper_format_stream_read_line(Stream* stream, string_t str_result)
|
||||
} else if(data == flipper_format_eolr) {
|
||||
// Ignore
|
||||
} else {
|
||||
string_push_back(str_result, data);
|
||||
furi_string_push_back(str_result, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +223,7 @@ static bool flipper_format_stream_read_line(Stream* stream, string_t str_result)
|
||||
}
|
||||
} while(true);
|
||||
|
||||
return string_size(str_result) != 0;
|
||||
return furi_string_size(str_result) != 0;
|
||||
}
|
||||
|
||||
static bool flipper_format_stream_seek_to_next_line(Stream* stream) {
|
||||
@@ -254,8 +267,8 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa
|
||||
if(write_data->type == FlipperStreamValueIgnore) {
|
||||
result = true;
|
||||
} else {
|
||||
string_t value;
|
||||
string_init(value);
|
||||
FuriString* value;
|
||||
value = furi_string_alloc();
|
||||
|
||||
do {
|
||||
if(!flipper_format_stream_write_key(stream, write_data->key)) break;
|
||||
@@ -267,45 +280,45 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa
|
||||
switch(write_data->type) {
|
||||
case FlipperStreamValueStr: {
|
||||
const char* data = write_data->data;
|
||||
string_printf(value, "%s", data);
|
||||
furi_string_printf(value, "%s", data);
|
||||
}; break;
|
||||
case FlipperStreamValueHex: {
|
||||
const uint8_t* data = write_data->data;
|
||||
string_printf(value, "%02X", data[i]);
|
||||
furi_string_printf(value, "%02X", data[i]);
|
||||
}; break;
|
||||
#ifndef FLIPPER_STREAM_LITE
|
||||
case FlipperStreamValueFloat: {
|
||||
const float* data = write_data->data;
|
||||
string_printf(value, "%f", (double)data[i]);
|
||||
furi_string_printf(value, "%f", (double)data[i]);
|
||||
}; break;
|
||||
#endif
|
||||
case FlipperStreamValueInt32: {
|
||||
const int32_t* data = write_data->data;
|
||||
string_printf(value, "%" PRIi32, data[i]);
|
||||
furi_string_printf(value, "%" PRIi32, data[i]);
|
||||
}; break;
|
||||
case FlipperStreamValueUint32: {
|
||||
const uint32_t* data = write_data->data;
|
||||
string_printf(value, "%" PRId32, data[i]);
|
||||
furi_string_printf(value, "%" PRId32, data[i]);
|
||||
}; break;
|
||||
case FlipperStreamValueHexUint64: {
|
||||
const uint64_t* data = write_data->data;
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
value, "%08lX%08lX", (uint32_t)(data[i] >> 32), (uint32_t)data[i]);
|
||||
}; break;
|
||||
case FlipperStreamValueBool: {
|
||||
const bool* data = write_data->data;
|
||||
string_printf(value, data[i] ? "true" : "false");
|
||||
furi_string_printf(value, data[i] ? "true" : "false");
|
||||
}; break;
|
||||
default:
|
||||
furi_crash("Unknown FF type");
|
||||
}
|
||||
|
||||
if((size_t)(i + 1) < write_data->data_size) {
|
||||
string_cat(value, " ");
|
||||
furi_string_cat(value, " ");
|
||||
}
|
||||
|
||||
if(!flipper_format_stream_write(
|
||||
stream, string_get_cstr(value), string_size(value))) {
|
||||
stream, furi_string_get_cstr(value), furi_string_size(value))) {
|
||||
cycle_error = true;
|
||||
break;
|
||||
}
|
||||
@@ -316,7 +329,7 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa
|
||||
result = true;
|
||||
} while(false);
|
||||
|
||||
string_clear(value);
|
||||
furi_string_free(value);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -335,15 +348,15 @@ bool flipper_format_stream_read_value_line(
|
||||
if(!flipper_format_stream_seek_to_key(stream, key, strict_mode)) break;
|
||||
|
||||
if(type == FlipperStreamValueStr) {
|
||||
string_ptr data = (string_ptr)_data;
|
||||
FuriString* data = (FuriString*)_data;
|
||||
if(flipper_format_stream_read_line(stream, data)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
result = true;
|
||||
string_t value;
|
||||
string_init(value);
|
||||
FuriString* value;
|
||||
value = furi_string_alloc();
|
||||
|
||||
for(size_t i = 0; i < data_size; i++) {
|
||||
bool last = false;
|
||||
@@ -354,11 +367,11 @@ bool flipper_format_stream_read_value_line(
|
||||
switch(type) {
|
||||
case FlipperStreamValueHex: {
|
||||
uint8_t* data = _data;
|
||||
if(string_size(value) >= 2) {
|
||||
if(furi_string_size(value) >= 2) {
|
||||
// sscanf "%02X" does not work here
|
||||
if(hex_char_to_uint8(
|
||||
string_get_char(value, 0),
|
||||
string_get_char(value, 1),
|
||||
furi_string_get_char(value, 0),
|
||||
furi_string_get_char(value, 1),
|
||||
&data[i])) {
|
||||
scan_values = 1;
|
||||
}
|
||||
@@ -368,9 +381,9 @@ bool flipper_format_stream_read_value_line(
|
||||
case FlipperStreamValueFloat: {
|
||||
float* data = _data;
|
||||
// newlib-nano does not have sscanf for floats
|
||||
// scan_values = sscanf(string_get_cstr(value), "%f", &data[i]);
|
||||
// scan_values = sscanf(furi_string_get_cstr(value), "%f", &data[i]);
|
||||
char* end_char;
|
||||
data[i] = strtof(string_get_cstr(value), &end_char);
|
||||
data[i] = strtof(furi_string_get_cstr(value), &end_char);
|
||||
if(*end_char == 0) {
|
||||
// most likely ok
|
||||
scan_values = 1;
|
||||
@@ -379,23 +392,23 @@ bool flipper_format_stream_read_value_line(
|
||||
#endif
|
||||
case FlipperStreamValueInt32: {
|
||||
int32_t* data = _data;
|
||||
scan_values = sscanf(string_get_cstr(value), "%" PRIi32, &data[i]);
|
||||
scan_values = sscanf(furi_string_get_cstr(value), "%" PRIi32, &data[i]);
|
||||
}; break;
|
||||
case FlipperStreamValueUint32: {
|
||||
uint32_t* data = _data;
|
||||
scan_values = sscanf(string_get_cstr(value), "%" PRId32, &data[i]);
|
||||
scan_values = sscanf(furi_string_get_cstr(value), "%" PRId32, &data[i]);
|
||||
}; break;
|
||||
case FlipperStreamValueHexUint64: {
|
||||
uint64_t* data = _data;
|
||||
if(string_size(value) >= 16) {
|
||||
if(hex_chars_to_uint64(string_get_cstr(value), &data[i])) {
|
||||
if(furi_string_size(value) >= 16) {
|
||||
if(hex_chars_to_uint64(furi_string_get_cstr(value), &data[i])) {
|
||||
scan_values = 1;
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
case FlipperStreamValueBool: {
|
||||
bool* data = _data;
|
||||
data[i] = !string_cmpi_str(value, "true");
|
||||
data[i] = !furi_string_cmpi(value, "true");
|
||||
scan_values = 1;
|
||||
}; break;
|
||||
default:
|
||||
@@ -416,7 +429,7 @@ bool flipper_format_stream_read_value_line(
|
||||
}
|
||||
}
|
||||
|
||||
string_clear(value);
|
||||
furi_string_free(value);
|
||||
}
|
||||
} while(false);
|
||||
|
||||
@@ -431,8 +444,8 @@ bool flipper_format_stream_get_value_count(
|
||||
bool result = false;
|
||||
bool last = false;
|
||||
|
||||
string_t value;
|
||||
string_init(value);
|
||||
FuriString* value;
|
||||
value = furi_string_alloc();
|
||||
|
||||
uint32_t position = stream_tell(stream);
|
||||
do {
|
||||
@@ -456,7 +469,7 @@ bool flipper_format_stream_get_value_count(
|
||||
result = false;
|
||||
}
|
||||
|
||||
string_clear(value);
|
||||
furi_string_free(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include <mlib/m-string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <furi.h>
|
||||
|
||||
#include <notification/notification_messages.h>
|
||||
#include <stream_buffer.h>
|
||||
|
||||
#define INFRARED_WORKER_RX_TIMEOUT INFRARED_RAW_RX_TIMING_DELAY_US
|
||||
|
||||
@@ -50,7 +49,7 @@ struct InfraredWorkerSignal {
|
||||
|
||||
struct InfraredWorker {
|
||||
FuriThread* thread;
|
||||
StreamBufferHandle_t stream;
|
||||
FuriStreamBuffer* stream;
|
||||
|
||||
InfraredWorkerSignal signal;
|
||||
InfraredWorkerState state;
|
||||
@@ -100,15 +99,13 @@ static void infrared_worker_rx_timeout_callback(void* context) {
|
||||
static void infrared_worker_rx_callback(void* context, bool level, uint32_t duration) {
|
||||
InfraredWorker* instance = context;
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
furi_assert(duration != 0);
|
||||
LevelDuration level_duration = level_duration_make(level, duration);
|
||||
|
||||
size_t ret = xStreamBufferSendFromISR(
|
||||
instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken);
|
||||
size_t ret =
|
||||
furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0);
|
||||
uint32_t events = (ret == sizeof(LevelDuration)) ? INFRARED_WORKER_RX_RECEIVED :
|
||||
INFRARED_WORKER_OVERRUN;
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
|
||||
uint32_t flags_set = furi_thread_flags_set(furi_thread_get_id(instance->thread), events);
|
||||
furi_check(flags_set & events);
|
||||
@@ -179,7 +176,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) {
|
||||
if(instance->signal.timings_cnt == 0)
|
||||
notification_message(instance->notification, &sequence_display_backlight_on);
|
||||
while(sizeof(LevelDuration) ==
|
||||
xStreamBufferReceive(
|
||||
furi_stream_buffer_receive(
|
||||
instance->stream, &level_duration, sizeof(LevelDuration), 0)) {
|
||||
if(!instance->rx.overrun) {
|
||||
bool level = level_duration_get_level(level_duration);
|
||||
@@ -232,7 +229,7 @@ InfraredWorker* infrared_worker_alloc() {
|
||||
size_t buffer_size =
|
||||
MAX(sizeof(InfraredWorkerTiming) * (MAX_TIMINGS_AMOUNT + 1),
|
||||
sizeof(LevelDuration) * MAX_TIMINGS_AMOUNT);
|
||||
instance->stream = xStreamBufferCreate(buffer_size, sizeof(InfraredWorkerTiming));
|
||||
instance->stream = furi_stream_buffer_alloc(buffer_size, sizeof(InfraredWorkerTiming));
|
||||
instance->infrared_decoder = infrared_alloc_decoder();
|
||||
instance->infrared_encoder = infrared_alloc_encoder();
|
||||
instance->blink_enable = false;
|
||||
@@ -249,7 +246,7 @@ void infrared_worker_free(InfraredWorker* instance) {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
infrared_free_decoder(instance->infrared_decoder);
|
||||
infrared_free_encoder(instance->infrared_encoder);
|
||||
vStreamBufferDelete(instance->stream);
|
||||
furi_stream_buffer_free(instance->stream);
|
||||
furi_thread_free(instance->thread);
|
||||
|
||||
free(instance);
|
||||
@@ -259,7 +256,7 @@ void infrared_worker_rx_start(InfraredWorker* instance) {
|
||||
furi_assert(instance);
|
||||
furi_assert(instance->state == InfraredWorkerStateIdle);
|
||||
|
||||
xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration));
|
||||
furi_stream_set_trigger_level(instance->stream, sizeof(LevelDuration));
|
||||
|
||||
furi_thread_set_callback(instance->thread, infrared_worker_rx_thread);
|
||||
furi_thread_start(instance->thread);
|
||||
@@ -285,9 +282,9 @@ void infrared_worker_rx_stop(InfraredWorker* instance) {
|
||||
furi_thread_flags_set(furi_thread_get_id(instance->thread), INFRARED_WORKER_EXIT);
|
||||
furi_thread_join(instance->thread);
|
||||
|
||||
BaseType_t xReturn = xStreamBufferReset(instance->stream);
|
||||
furi_assert(xReturn == pdPASS);
|
||||
(void)xReturn;
|
||||
FuriStatus status = furi_stream_buffer_reset(instance->stream);
|
||||
furi_assert(status == FuriStatusOk);
|
||||
(void)status;
|
||||
|
||||
instance->state = InfraredWorkerStateIdle;
|
||||
}
|
||||
@@ -325,7 +322,7 @@ void infrared_worker_tx_start(InfraredWorker* instance) {
|
||||
furi_assert(instance->tx.get_signal_callback);
|
||||
|
||||
// size have to be greater than api hal infrared async tx buffer size
|
||||
xStreamBufferSetTriggerLevel(instance->stream, sizeof(InfraredWorkerTiming));
|
||||
furi_stream_set_trigger_level(instance->stream, sizeof(InfraredWorkerTiming));
|
||||
|
||||
furi_thread_set_callback(instance->thread, infrared_worker_tx_thread);
|
||||
|
||||
@@ -358,7 +355,7 @@ static FuriHalInfraredTxGetDataState
|
||||
FuriHalInfraredTxGetDataState state;
|
||||
|
||||
if(sizeof(InfraredWorkerTiming) ==
|
||||
xStreamBufferReceiveFromISR(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) {
|
||||
furi_stream_buffer_receive(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) {
|
||||
*level = timing.level;
|
||||
*duration = timing.duration;
|
||||
state = timing.state;
|
||||
@@ -420,7 +417,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) {
|
||||
InfraredWorkerTiming timing;
|
||||
InfraredStatus status = InfraredStatusError;
|
||||
|
||||
while(!xStreamBufferIsFull(instance->stream) && !instance->tx.need_reinitialization &&
|
||||
while(!furi_stream_buffer_is_full(instance->stream) && !instance->tx.need_reinitialization &&
|
||||
new_data_available) {
|
||||
if(instance->signal.decoded) {
|
||||
status = infrared_encode(instance->infrared_encoder, &timing.duration, &timing.level);
|
||||
@@ -454,7 +451,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) {
|
||||
furi_assert(0);
|
||||
}
|
||||
uint32_t written_size =
|
||||
xStreamBufferSend(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0);
|
||||
furi_stream_buffer_send(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0);
|
||||
furi_assert(sizeof(InfraredWorkerTiming) == written_size);
|
||||
(void)written_size;
|
||||
}
|
||||
@@ -564,10 +561,9 @@ void infrared_worker_tx_stop(InfraredWorker* instance) {
|
||||
furi_hal_infrared_async_tx_set_signal_sent_isr_callback(NULL, NULL);
|
||||
|
||||
instance->signal.timings_cnt = 0;
|
||||
BaseType_t xReturn = pdFAIL;
|
||||
xReturn = xStreamBufferReset(instance->stream);
|
||||
furi_assert(xReturn == pdPASS);
|
||||
(void)xReturn;
|
||||
FuriStatus status = furi_stream_buffer_reset(instance->stream);
|
||||
furi_assert(status == FuriStatusOk);
|
||||
(void)status;
|
||||
instance->state = InfraredWorkerStateIdle;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,8 +143,8 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) {
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
ProtocolId result = PROTOCOL_NO;
|
||||
uint8_t* data = malloc(protocol_dict_get_max_data_size(dict));
|
||||
string_t str_result;
|
||||
string_init(str_result);
|
||||
FuriString* str_result;
|
||||
str_result = furi_string_alloc();
|
||||
|
||||
do {
|
||||
if(!flipper_format_file_open_existing(file, filename)) break;
|
||||
@@ -152,16 +152,16 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) {
|
||||
// header
|
||||
uint32_t version;
|
||||
if(!flipper_format_read_header(file, str_result, &version)) break;
|
||||
if(string_cmp_str(str_result, LFRFID_DICT_FILETYPE) != 0) break;
|
||||
if(furi_string_cmp_str(str_result, LFRFID_DICT_FILETYPE) != 0) break;
|
||||
if(version != 1) break;
|
||||
|
||||
// type
|
||||
if(!flipper_format_read_string(file, "Key type", str_result)) break;
|
||||
ProtocolId protocol;
|
||||
protocol = protocol_dict_get_protocol_by_name(dict, string_get_cstr(str_result));
|
||||
protocol = protocol_dict_get_protocol_by_name(dict, furi_string_get_cstr(str_result));
|
||||
|
||||
if(protocol == PROTOCOL_NO) {
|
||||
protocol = lfrfid_dict_protocol_fallback(dict, string_get_cstr(str_result), file);
|
||||
protocol = lfrfid_dict_protocol_fallback(dict, furi_string_get_cstr(str_result), file);
|
||||
if(protocol == PROTOCOL_NO) break;
|
||||
} else {
|
||||
// data
|
||||
@@ -174,7 +174,7 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) {
|
||||
} while(false);
|
||||
|
||||
free(data);
|
||||
string_clear(str_result);
|
||||
furi_string_free(str_result);
|
||||
flipper_format_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <toolbox/stream/file_stream.h>
|
||||
#include <toolbox/buffer_stream.h>
|
||||
#include <toolbox/varint.h>
|
||||
#include <stream_buffer.h>
|
||||
#include "lfrfid_raw_worker.h"
|
||||
#include "lfrfid_raw_file.h"
|
||||
#include "tools/varint_pair.h"
|
||||
@@ -16,7 +15,7 @@
|
||||
// emulate mode
|
||||
typedef struct {
|
||||
size_t overrun_count;
|
||||
StreamBufferHandle_t stream;
|
||||
FuriStreamBuffer* stream;
|
||||
} RfidEmulateCtx;
|
||||
|
||||
typedef struct {
|
||||
@@ -40,7 +39,7 @@ typedef struct {
|
||||
|
||||
// main worker
|
||||
struct LFRFIDRawWorker {
|
||||
string_t file_path;
|
||||
FuriString* file_path;
|
||||
FuriThread* thread;
|
||||
FuriEventFlag* events;
|
||||
|
||||
@@ -69,14 +68,14 @@ LFRFIDRawWorker* lfrfid_raw_worker_alloc() {
|
||||
|
||||
worker->events = furi_event_flag_alloc(NULL);
|
||||
|
||||
string_init(worker->file_path);
|
||||
worker->file_path = furi_string_alloc();
|
||||
return worker;
|
||||
}
|
||||
|
||||
void lfrfid_raw_worker_free(LFRFIDRawWorker* worker) {
|
||||
furi_thread_free(worker->thread);
|
||||
furi_event_flag_free(worker->events);
|
||||
string_clear(worker->file_path);
|
||||
furi_string_free(worker->file_path);
|
||||
free(worker);
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ void lfrfid_raw_worker_start_read(
|
||||
void* context) {
|
||||
furi_check(furi_thread_get_state(worker->thread) == FuriThreadStateStopped);
|
||||
|
||||
string_set(worker->file_path, file_path);
|
||||
furi_string_set(worker->file_path, file_path);
|
||||
|
||||
worker->frequency = freq;
|
||||
worker->duty_cycle = duty_cycle;
|
||||
@@ -107,7 +106,7 @@ void lfrfid_raw_worker_start_emulate(
|
||||
LFRFIDWorkerEmulateRawCallback callback,
|
||||
void* context) {
|
||||
furi_check(furi_thread_get_state(worker->thread) == FuriThreadStateStopped);
|
||||
string_set(worker->file_path, file_path);
|
||||
furi_string_set(worker->file_path, file_path);
|
||||
worker->emulate_callback = callback;
|
||||
worker->context = context;
|
||||
furi_thread_set_callback(worker->thread, lfrfid_raw_emulate_worker_thread);
|
||||
@@ -126,20 +125,13 @@ void lfrfid_raw_worker_stop(LFRFIDRawWorker* worker) {
|
||||
static void lfrfid_raw_worker_capture(bool level, uint32_t duration, void* context) {
|
||||
LFRFIDRawWorkerReadData* ctx = context;
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
bool need_to_send = varint_pair_pack(ctx->pair, level, duration);
|
||||
|
||||
if(need_to_send) {
|
||||
buffer_stream_send_from_isr(
|
||||
ctx->stream,
|
||||
varint_pair_get_data(ctx->pair),
|
||||
varint_pair_get_size(ctx->pair),
|
||||
&xHigherPriorityTaskWoken);
|
||||
ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair));
|
||||
varint_pair_reset(ctx->pair);
|
||||
}
|
||||
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
static int32_t lfrfid_raw_read_worker_thread(void* thread_context) {
|
||||
@@ -147,7 +139,7 @@ static int32_t lfrfid_raw_read_worker_thread(void* thread_context) {
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage);
|
||||
const char* filename = string_get_cstr(worker->file_path);
|
||||
const char* filename = furi_string_get_cstr(worker->file_path);
|
||||
bool file_valid = lfrfid_raw_file_open_write(file, filename);
|
||||
|
||||
LFRFIDRawWorkerReadData* data = malloc(sizeof(LFRFIDRawWorkerReadData));
|
||||
@@ -236,7 +228,7 @@ static void rfid_emulate_dma_isr(bool half, void* context) {
|
||||
RfidEmulateCtx* ctx = context;
|
||||
|
||||
uint32_t flag = half ? HalfTransfer : TransferComplete;
|
||||
size_t len = xStreamBufferSendFromISR(ctx->stream, &flag, sizeof(uint32_t), pdFALSE);
|
||||
size_t len = furi_stream_buffer_send(ctx->stream, &flag, sizeof(uint32_t), 0);
|
||||
if(len != sizeof(uint32_t)) {
|
||||
ctx->overrun_count++;
|
||||
}
|
||||
@@ -251,12 +243,12 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) {
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
data->ctx.overrun_count = 0;
|
||||
data->ctx.stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t));
|
||||
data->ctx.stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t));
|
||||
|
||||
LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage);
|
||||
|
||||
do {
|
||||
file_valid = lfrfid_raw_file_open_read(file, string_get_cstr(worker->file_path));
|
||||
file_valid = lfrfid_raw_file_open_read(file, furi_string_get_cstr(worker->file_path));
|
||||
if(!file_valid) break;
|
||||
file_valid = lfrfid_raw_file_read_header(file, &worker->frequency, &worker->duty_cycle);
|
||||
if(!file_valid) break;
|
||||
@@ -287,7 +279,8 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) {
|
||||
uint32_t flag = 0;
|
||||
|
||||
while(true) {
|
||||
size_t size = xStreamBufferReceive(data->ctx.stream, &flag, sizeof(uint32_t), 100);
|
||||
size_t size =
|
||||
furi_stream_buffer_receive(data->ctx.stream, &flag, sizeof(uint32_t), 100);
|
||||
|
||||
if(size == sizeof(uint32_t)) {
|
||||
size_t start = 0;
|
||||
@@ -345,10 +338,10 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) {
|
||||
}
|
||||
|
||||
if(data->ctx.overrun_count) {
|
||||
FURI_LOG_E(TAG_EMULATE, "overruns: %lu", data->ctx.overrun_count);
|
||||
FURI_LOG_E(TAG_EMULATE, "overruns: %u", data->ctx.overrun_count);
|
||||
}
|
||||
|
||||
vStreamBufferDelete(data->ctx.stream);
|
||||
furi_stream_buffer_free(data->ctx.stream);
|
||||
lfrfid_raw_file_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
free(data);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <furi_hal.h>
|
||||
#include "lfrfid_worker_i.h"
|
||||
#include "tools/t5577.h"
|
||||
#include <stream_buffer.h>
|
||||
#include <toolbox/pulse_protocols/pulse_glue.h>
|
||||
#include <toolbox/buffer_stream.h>
|
||||
#include "tools/varint_pair.h"
|
||||
@@ -81,17 +80,12 @@ static void lfrfid_worker_read_capture(bool level, uint32_t duration, void* cont
|
||||
furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, level);
|
||||
#endif
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
bool need_to_send = varint_pair_pack(ctx->pair, level, duration);
|
||||
if(need_to_send) {
|
||||
buffer_stream_send_from_isr(
|
||||
ctx->stream,
|
||||
varint_pair_get_data(ctx->pair),
|
||||
varint_pair_get_size(ctx->pair),
|
||||
&xHigherPriorityTaskWoken);
|
||||
ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair));
|
||||
varint_pair_reset(ctx->pair);
|
||||
}
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -270,14 +264,14 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal(
|
||||
}
|
||||
|
||||
if(furi_log_get_level() >= FuriLogLevelDebug) {
|
||||
string_t string_info;
|
||||
string_init(string_info);
|
||||
FuriString* string_info;
|
||||
string_info = furi_string_alloc();
|
||||
for(uint8_t i = 0; i < protocol_data_size; i++) {
|
||||
if(i != 0) {
|
||||
string_cat_printf(string_info, " ");
|
||||
furi_string_cat_printf(string_info, " ");
|
||||
}
|
||||
|
||||
string_cat_printf(string_info, "%02X", protocol_data[i]);
|
||||
furi_string_cat_printf(string_info, "%02X", protocol_data[i]);
|
||||
}
|
||||
|
||||
FURI_LOG_D(
|
||||
@@ -285,8 +279,8 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal(
|
||||
"%s, %d, [%s]",
|
||||
protocol_dict_get_name(worker->protocols, protocol),
|
||||
last_read_count,
|
||||
string_get_cstr(string_info));
|
||||
string_clear(string_info);
|
||||
furi_string_get_cstr(string_info));
|
||||
furi_string_free(string_info);
|
||||
}
|
||||
|
||||
protocol_dict_decoders_start(worker->protocols);
|
||||
@@ -407,14 +401,14 @@ typedef enum {
|
||||
} LFRFIDWorkerEmulateDMAEvent;
|
||||
|
||||
static void lfrfid_worker_emulate_dma_isr(bool half, void* context) {
|
||||
StreamBufferHandle_t stream = context;
|
||||
FuriStreamBuffer* stream = context;
|
||||
uint32_t flag = half ? HalfTransfer : TransferComplete;
|
||||
xStreamBufferSendFromISR(stream, &flag, sizeof(uint32_t), pdFALSE);
|
||||
furi_stream_buffer_send(stream, &flag, sizeof(uint32_t), 0);
|
||||
}
|
||||
|
||||
static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) {
|
||||
LFRFIDWorkerEmulateBuffer* buffer = malloc(sizeof(LFRFIDWorkerEmulateBuffer));
|
||||
StreamBufferHandle_t stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t));
|
||||
FuriStreamBuffer* stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t));
|
||||
LFRFIDProtocol protocol = worker->protocol;
|
||||
PulseGlue* pulse_glue = pulse_glue_alloc();
|
||||
|
||||
@@ -449,7 +443,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) {
|
||||
|
||||
while(true) {
|
||||
uint32_t flag = 0;
|
||||
size_t size = xStreamBufferReceive(stream, &flag, sizeof(uint32_t), 100);
|
||||
size_t size = furi_stream_buffer_receive(stream, &flag, sizeof(uint32_t), 100);
|
||||
|
||||
#ifdef LFRFID_WORKER_READ_DEBUG_GPIO
|
||||
furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, true);
|
||||
@@ -497,7 +491,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) {
|
||||
#endif
|
||||
|
||||
free(buffer);
|
||||
vStreamBufferDelete(stream);
|
||||
furi_stream_buffer_free(stream);
|
||||
pulse_glue_free(pulse_glue);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ LevelDuration protocol_awid_encoder_yield(ProtocolAwid* protocol) {
|
||||
return level_duration_make(level, duration);
|
||||
};
|
||||
|
||||
void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) {
|
||||
void protocol_awid_render_data(ProtocolAwid* protocol, FuriString* result) {
|
||||
// Index map
|
||||
// 0 10 20 30 40 50 60
|
||||
// | | | | | | |
|
||||
@@ -164,7 +164,7 @@ void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) {
|
||||
uint8_t* decoded_data = protocol->data;
|
||||
uint8_t format_length = decoded_data[0];
|
||||
|
||||
string_cat_printf(result, "Format: %d\r\n", format_length);
|
||||
furi_string_cat_printf(result, "Format: %d\r\n", format_length);
|
||||
if(format_length == 26) {
|
||||
uint8_t facility;
|
||||
bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9);
|
||||
@@ -172,22 +172,22 @@ void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) {
|
||||
uint16_t card_id;
|
||||
bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17);
|
||||
bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25);
|
||||
string_cat_printf(result, "Facility: %d\r\n", facility);
|
||||
string_cat_printf(result, "Card: %d", card_id);
|
||||
furi_string_cat_printf(result, "Facility: %d\r\n", facility);
|
||||
furi_string_cat_printf(result, "Card: %d", card_id);
|
||||
} else {
|
||||
// print 66 bits as hex
|
||||
string_cat_printf(result, "Data: ");
|
||||
furi_string_cat_printf(result, "Data: ");
|
||||
for(size_t i = 0; i < AWID_DECODED_DATA_SIZE; i++) {
|
||||
string_cat_printf(result, "%02X", decoded_data[i]);
|
||||
furi_string_cat_printf(result, "%02X", decoded_data[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void protocol_awid_render_brief_data(ProtocolAwid* protocol, string_t result) {
|
||||
void protocol_awid_render_brief_data(ProtocolAwid* protocol, FuriString* result) {
|
||||
uint8_t* decoded_data = protocol->data;
|
||||
uint8_t format_length = decoded_data[0];
|
||||
|
||||
string_cat_printf(result, "Format: %d\r\n", format_length);
|
||||
furi_string_cat_printf(result, "Format: %d\r\n", format_length);
|
||||
if(format_length == 26) {
|
||||
uint8_t facility;
|
||||
bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9);
|
||||
@@ -195,9 +195,9 @@ void protocol_awid_render_brief_data(ProtocolAwid* protocol, string_t result) {
|
||||
uint16_t card_id;
|
||||
bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17);
|
||||
bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25);
|
||||
string_cat_printf(result, "ID: %03u,%05u", facility, card_id);
|
||||
furi_string_cat_printf(result, "ID: %03u,%05u", facility, card_id);
|
||||
} else {
|
||||
string_cat_printf(result, "Data: unknown");
|
||||
furi_string_cat_printf(result, "Data: unknown");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -205,8 +205,15 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) {
|
||||
LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data;
|
||||
bool result = false;
|
||||
|
||||
// Fix incorrect length byte
|
||||
if(protocol->data[0] != 26 && protocol->data[0] != 50 && protocol->data[0] != 37 &&
|
||||
protocol->data[0] != 34) {
|
||||
protocol->data[0] = 26;
|
||||
}
|
||||
|
||||
// Correct protocol data by redecoding
|
||||
protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data);
|
||||
bit_lib_remove_bit_every_nth((uint8_t*)protocol->encoded_data, 8, 88, 4);
|
||||
protocol_awid_decode(protocol->encoded_data, protocol->data);
|
||||
|
||||
protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data);
|
||||
|
||||
@@ -251,10 +251,10 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) {
|
||||
// Correct protocol data by redecoding
|
||||
protocol_em4100_encoder_start(protocol);
|
||||
em4100_decode(
|
||||
(uint8_t*)&protocol->encoded_data,
|
||||
sizeof(EM4100DecodedData),
|
||||
protocol->data,
|
||||
EM4100_DECODED_DATA_SIZE);
|
||||
(uint8_t*)&protocol->encoded_data,
|
||||
sizeof(EM4100DecodedData),
|
||||
protocol->data,
|
||||
EM4100_DECODED_DATA_SIZE);
|
||||
|
||||
protocol_em4100_encoder_start(protocol);
|
||||
|
||||
@@ -270,9 +270,10 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_em4100_render_data(ProtocolEM4100* protocol, string_t result) {
|
||||
void protocol_em4100_render_data(ProtocolEM4100* protocol, FuriString* result) {
|
||||
uint8_t* data = protocol->data;
|
||||
string_printf(result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4])));
|
||||
furi_string_printf(
|
||||
result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4])));
|
||||
};
|
||||
|
||||
const ProtocolBase protocol_em4100 = {
|
||||
|
||||
@@ -79,6 +79,14 @@ static bool protocol_fdx_a_decode(const uint8_t* from, uint8_t* to) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void protocol_fdx_a_fix_parity(ProtocolFDXA* protocol) {
|
||||
for(size_t i = 0; i < FDXA_DECODED_DATA_SIZE; i++) {
|
||||
if(bit_lib_test_parity_32(protocol->data[i], BitLibParityOdd)) {
|
||||
protocol->data[i] ^= (1 << 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool protocol_fdx_a_can_be_decoded(const uint8_t* data) {
|
||||
// check preamble
|
||||
if(data[0] != FDXA_PREAMBLE_0 || data[1] != FDXA_PREAMBLE_1 || data[12] != FDXA_PREAMBLE_0 ||
|
||||
@@ -179,6 +187,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) {
|
||||
bool result = false;
|
||||
|
||||
// Correct protocol data by redecoding
|
||||
protocol_fdx_a_fix_parity(protocol);
|
||||
protocol_fdx_a_encoder_start(protocol);
|
||||
protocol_fdx_a_decode(protocol->encoded_data, protocol->data);
|
||||
|
||||
@@ -196,7 +205,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_fdx_a_render_data(ProtocolFDXA* protocol, string_t result) {
|
||||
void protocol_fdx_a_render_data(ProtocolFDXA* protocol, FuriString* result) {
|
||||
uint8_t data[FDXA_DECODED_DATA_SIZE];
|
||||
memcpy(data, protocol->data, FDXA_DECODED_DATA_SIZE);
|
||||
|
||||
@@ -206,7 +215,7 @@ void protocol_fdx_a_render_data(ProtocolFDXA* protocol, string_t result) {
|
||||
data[i] &= 0x7F;
|
||||
}
|
||||
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"ID: %02X%02X%02X%02X%02X\r\n"
|
||||
"Parity: %s",
|
||||
|
||||
@@ -273,7 +273,7 @@ static bool protocol_fdx_b_get_temp(const uint8_t* data, float* temp) {
|
||||
}
|
||||
}
|
||||
|
||||
void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) {
|
||||
void protocol_fdx_b_render_data(ProtocolFDXB* protocol, FuriString* result) {
|
||||
// 38 bits of national code
|
||||
uint64_t national_code = protocol_fdx_b_get_national_code(protocol->data);
|
||||
|
||||
@@ -287,19 +287,19 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) {
|
||||
uint8_t replacement_number = bit_lib_get_bits(protocol->data, 60, 3);
|
||||
bool animal_flag = bit_lib_get_bit(protocol->data, 63);
|
||||
|
||||
string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code);
|
||||
string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No");
|
||||
furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code);
|
||||
furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No");
|
||||
|
||||
float temperature;
|
||||
if(protocol_fdx_b_get_temp(protocol->data, &temperature)) {
|
||||
float temperature_c = (temperature - 32) / 1.8;
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
result, "T: %.2fF, %.2fC\r\n", (double)temperature, (double)temperature_c);
|
||||
} else {
|
||||
string_cat_printf(result, "T: ---\r\n");
|
||||
furi_string_cat_printf(result, "T: ---\r\n");
|
||||
}
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
result,
|
||||
"Bits: %X-%X-%X-%X-%X",
|
||||
block_status,
|
||||
@@ -309,7 +309,7 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) {
|
||||
replacement_number);
|
||||
};
|
||||
|
||||
void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, string_t result) {
|
||||
void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, FuriString* result) {
|
||||
// 38 bits of national code
|
||||
uint64_t national_code = protocol_fdx_b_get_national_code(protocol->data);
|
||||
|
||||
@@ -318,15 +318,15 @@ void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, string_t result) {
|
||||
|
||||
bool animal_flag = bit_lib_get_bit(protocol->data, 63);
|
||||
|
||||
string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code);
|
||||
string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No");
|
||||
furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code);
|
||||
furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No");
|
||||
|
||||
float temperature;
|
||||
if(protocol_fdx_b_get_temp(protocol->data, &temperature)) {
|
||||
float temperature_c = (temperature - 32) / 1.8;
|
||||
string_cat_printf(result, "T: %.2fC", (double)temperature_c);
|
||||
furi_string_cat_printf(result, "T: %.2fC", (double)temperature_c);
|
||||
} else {
|
||||
string_cat_printf(result, "T: ---");
|
||||
furi_string_cat_printf(result, "T: ---");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -268,15 +268,15 @@ bool protocol_gallagher_write_data(ProtocolGallagher* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_gallagher_render_data(ProtocolGallagher* protocol, string_t result) {
|
||||
void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* result) {
|
||||
UNUSED(protocol);
|
||||
uint8_t rc = bit_lib_get_bits(protocol->data, 0, 4);
|
||||
uint8_t il = bit_lib_get_bits(protocol->data, 4, 4);
|
||||
uint32_t fc = bit_lib_get_bits_32(protocol->data, 8, 24);
|
||||
uint32_t card_id = bit_lib_get_bits_32(protocol->data, 32, 32);
|
||||
|
||||
string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il);
|
||||
string_cat_printf(result, "FC: %u, C: %lu\r\n", fc, card_id);
|
||||
furi_string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il);
|
||||
furi_string_cat_printf(result, "FC: %lu, C: %lu\r\n", fc, card_id);
|
||||
};
|
||||
|
||||
const ProtocolBase protocol_gallagher = {
|
||||
|
||||
@@ -340,7 +340,7 @@ bool protocol_h10301_write_data(ProtocolH10301* protocol, void* data) {
|
||||
// Correct protocol data by redecoding
|
||||
protocol_h10301_encoder_start(protocol);
|
||||
protocol_h10301_decode(protocol->encoded_data, protocol->data);
|
||||
|
||||
|
||||
protocol_h10301_encoder_start(protocol);
|
||||
|
||||
if(request->write_type == LFRFIDWriteTypeT5577) {
|
||||
@@ -355,9 +355,9 @@ bool protocol_h10301_write_data(ProtocolH10301* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_h10301_render_data(ProtocolH10301* protocol, string_t result) {
|
||||
void protocol_h10301_render_data(ProtocolH10301* protocol, FuriString* result) {
|
||||
uint8_t* data = protocol->data;
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"FC: %u\r\n"
|
||||
"Card: %u",
|
||||
|
||||
@@ -192,10 +192,10 @@ bool protocol_hid_ex_generic_write_data(ProtocolHIDEx* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, string_t result) {
|
||||
void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, FuriString* result) {
|
||||
// TODO: parser and render functions
|
||||
UNUSED(protocol);
|
||||
string_printf(result, "Generic HID Extended\r\nData: Unknown");
|
||||
furi_string_printf(result, "Generic HID Extended\r\nData: Unknown");
|
||||
};
|
||||
|
||||
const ProtocolBase protocol_hid_ex_generic = {
|
||||
|
||||
@@ -221,25 +221,29 @@ bool protocol_hid_generic_write_data(ProtocolHID* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
static void protocol_hid_generic_string_cat_protocol_bits(ProtocolHID* protocol, uint8_t protocol_size, string_t result) {
|
||||
static void protocol_hid_generic_string_cat_protocol_bits(
|
||||
ProtocolHID* protocol,
|
||||
uint8_t protocol_size,
|
||||
FuriString* result) {
|
||||
// round up to the nearest nibble
|
||||
const uint8_t hex_character_count = (protocol_size + 3) / 4;
|
||||
const uint8_t protocol_bit_index = HID_DECODED_BIT_SIZE - protocol_size;
|
||||
|
||||
for(size_t i = 0; i < hex_character_count; i++) {
|
||||
uint8_t nibble =
|
||||
i == 0 ? bit_lib_get_bits(
|
||||
protocol->data, protocol_bit_index, protocol_size % 4 == 0 ? 4 : protocol_size % 4) :
|
||||
bit_lib_get_bits(protocol->data, protocol_bit_index + i * 4, 4);
|
||||
string_cat_printf(result, "%X", nibble & 0xF);
|
||||
uint8_t nibble = i == 0 ? bit_lib_get_bits(
|
||||
protocol->data,
|
||||
protocol_bit_index,
|
||||
protocol_size % 4 == 0 ? 4 : protocol_size % 4) :
|
||||
bit_lib_get_bits(protocol->data, protocol_bit_index + i * 4, 4);
|
||||
furi_string_cat_printf(result, "%X", nibble & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
void protocol_hid_generic_render_data(ProtocolHID* protocol, string_t result) {
|
||||
void protocol_hid_generic_render_data(ProtocolHID* protocol, FuriString* result) {
|
||||
const uint8_t protocol_size = protocol_hid_generic_decode_protocol_size(protocol);
|
||||
|
||||
if(protocol_size == HID_PROTOCOL_SIZE_UNKNOWN) {
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"Generic HID Proximity\r\n"
|
||||
"Data: %02X%02X%02X%02X%02X%X",
|
||||
@@ -250,7 +254,7 @@ void protocol_hid_generic_render_data(ProtocolHID* protocol, string_t result) {
|
||||
protocol->data[4],
|
||||
protocol->data[5] >> 4);
|
||||
} else {
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"%hhu-bit HID Proximity\r\n"
|
||||
"Data: ",
|
||||
|
||||
@@ -236,7 +236,10 @@ static uint16_t get_cn(const uint8_t* data) {
|
||||
return cn;
|
||||
}
|
||||
|
||||
void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t result, bool brief) {
|
||||
void protocol_indala26_render_data_internal(
|
||||
ProtocolIndala* protocol,
|
||||
FuriString* result,
|
||||
bool brief) {
|
||||
bool wiegand_correct = true;
|
||||
bool checksum_correct = true;
|
||||
|
||||
@@ -284,7 +287,7 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r
|
||||
if(odd_parity_sum % 2 != odd_parity) wiegand_correct = false;
|
||||
|
||||
if(brief) {
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"FC: %u\r\nCard: %u, Parity:%s%s",
|
||||
fc,
|
||||
@@ -292,7 +295,7 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r
|
||||
(checksum_correct ? "+" : "-"),
|
||||
(wiegand_correct ? "+" : "-"));
|
||||
} else {
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"FC: %u\r\n"
|
||||
"Card: %u\r\n"
|
||||
@@ -304,10 +307,10 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r
|
||||
(wiegand_correct ? "+" : "-"));
|
||||
}
|
||||
}
|
||||
void protocol_indala26_render_data(ProtocolIndala* protocol, string_t result) {
|
||||
void protocol_indala26_render_data(ProtocolIndala* protocol, FuriString* result) {
|
||||
protocol_indala26_render_data_internal(protocol, result, false);
|
||||
}
|
||||
void protocol_indala26_render_brief_data(ProtocolIndala* protocol, string_t result) {
|
||||
void protocol_indala26_render_brief_data(ProtocolIndala* protocol, FuriString* result) {
|
||||
protocol_indala26_render_data_internal(protocol, result, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,9 +232,9 @@ LevelDuration protocol_io_prox_xsf_encoder_yield(ProtocolIOProxXSF* protocol) {
|
||||
return level_duration_make(level, duration);
|
||||
};
|
||||
|
||||
void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, string_t result) {
|
||||
void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, FuriString* result) {
|
||||
uint8_t* data = protocol->data;
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"FC: %u\r\n"
|
||||
"VС: %u\r\n"
|
||||
@@ -244,9 +244,9 @@ void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, string_t resu
|
||||
(uint16_t)((data[2] << 8) | (data[3])));
|
||||
}
|
||||
|
||||
void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, string_t result) {
|
||||
void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, FuriString* result) {
|
||||
uint8_t* data = protocol->data;
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
result,
|
||||
"FC: %u, VС: %u\r\n"
|
||||
"Card: %u",
|
||||
|
||||
@@ -160,9 +160,9 @@ LevelDuration protocol_jablotron_encoder_yield(ProtocolJablotron* protocol) {
|
||||
return level_duration_make(protocol->last_level, duration);
|
||||
};
|
||||
|
||||
void protocol_jablotron_render_data(ProtocolJablotron* protocol, string_t result) {
|
||||
void protocol_jablotron_render_data(ProtocolJablotron* protocol, FuriString* result) {
|
||||
uint64_t id = protocol_jablotron_card_id(protocol->data);
|
||||
string_printf(result, "ID: %llX\r\n", id);
|
||||
furi_string_printf(result, "ID: %llX\r\n", id);
|
||||
};
|
||||
|
||||
bool protocol_jablotron_write_data(ProtocolJablotron* protocol, void* data) {
|
||||
|
||||
@@ -170,6 +170,7 @@ bool protocol_keri_encoder_start(ProtocolKeri* protocol) {
|
||||
memset(protocol->encoded_data, 0, KERI_ENCODED_DATA_SIZE);
|
||||
*(uint32_t*)&protocol->encoded_data[0] = 0b00000000000000000000000011100000;
|
||||
bit_lib_copy_bits(protocol->encoded_data, 32, 32, protocol->data, 0);
|
||||
bit_lib_set_bits(protocol->encoded_data, 32, 1, 1);
|
||||
|
||||
protocol->encoder.last_bit =
|
||||
bit_lib_get_bit(protocol->encoded_data, KERI_ENCODED_BIT_SIZE - 1);
|
||||
@@ -211,19 +212,21 @@ LevelDuration protocol_keri_encoder_yield(ProtocolKeri* protocol) {
|
||||
return level_duration;
|
||||
};
|
||||
|
||||
void protocol_keri_render_data(ProtocolKeri* protocol, string_t result) {
|
||||
void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) {
|
||||
uint32_t data = bit_lib_get_bits_32(protocol->data, 0, 32);
|
||||
uint32_t internal_id = data & 0x7FFFFFFF;
|
||||
uint32_t fc = 0;
|
||||
uint32_t cn = 0;
|
||||
protocol_keri_descramble(&fc, &cn, &data);
|
||||
string_printf(result, "Internal ID: %u\r\nFC: %u, Card: %u\r\n", internal_id, fc, cn);
|
||||
furi_string_printf(result, "Internal ID: %lu\r\nFC: %lu, Card: %lu\r\n", internal_id, fc, cn);
|
||||
}
|
||||
|
||||
bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) {
|
||||
LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data;
|
||||
bool result = false;
|
||||
|
||||
// Start bit should be always set
|
||||
protocol->data[0] |= (1 << 7);
|
||||
protocol_keri_encoder_start(protocol);
|
||||
|
||||
if(request->write_type == LFRFIDWriteTypeT5577) {
|
||||
|
||||
@@ -57,31 +57,31 @@ static void protocol_pac_stanley_decode(ProtocolPACStanley* protocol) {
|
||||
}
|
||||
|
||||
static bool protocol_pac_stanley_can_be_decoded(ProtocolPACStanley* protocol) {
|
||||
// Check preamble
|
||||
if(bit_lib_get_bits(protocol->encoded_data, 0, 8) != 0b11111111) return false;
|
||||
if(bit_lib_get_bit(protocol->encoded_data, 8) != 0) return false;
|
||||
if(bit_lib_get_bit(protocol->encoded_data, 9) != 0) return false;
|
||||
if(bit_lib_get_bit(protocol->encoded_data, 10) != 1) return false;
|
||||
if(bit_lib_get_bits(protocol->encoded_data, 11, 8) != 0b00000010) return false;
|
||||
// Check preamble
|
||||
if(bit_lib_get_bits(protocol->encoded_data, 0, 8) != 0b11111111) return false;
|
||||
if(bit_lib_get_bit(protocol->encoded_data, 8) != 0) return false;
|
||||
if(bit_lib_get_bit(protocol->encoded_data, 9) != 0) return false;
|
||||
if(bit_lib_get_bit(protocol->encoded_data, 10) != 1) return false;
|
||||
if(bit_lib_get_bits(protocol->encoded_data, 11, 8) != 0b00000010) return false;
|
||||
|
||||
// Check next preamble
|
||||
if(bit_lib_get_bits(protocol->encoded_data, 128, 8) != 0b11111111) return false;
|
||||
// Check next preamble
|
||||
if(bit_lib_get_bits(protocol->encoded_data, 128, 8) != 0b11111111) return false;
|
||||
|
||||
// Checksum
|
||||
uint8_t checksum = 0;
|
||||
uint8_t stripped_byte;
|
||||
for(size_t idx = 0; idx < 9; idx++) {
|
||||
uint8_t byte = bit_lib_reverse_8_fast(bit_lib_get_bits(
|
||||
protocol->encoded_data,
|
||||
PAC_STANLEY_DATA_START_INDEX + (PAC_STANLEY_BYTE_LENGTH * idx),
|
||||
8));
|
||||
stripped_byte = byte & 0x7F; // discard the parity bit
|
||||
if(bit_lib_test_parity_32(stripped_byte, BitLibParityOdd) != (byte & 0x80) >> 7) {
|
||||
return false;
|
||||
}
|
||||
if(idx < 8) checksum ^= stripped_byte;
|
||||
// Checksum
|
||||
uint8_t checksum = 0;
|
||||
uint8_t stripped_byte;
|
||||
for(size_t idx = 0; idx < 9; idx++) {
|
||||
uint8_t byte = bit_lib_reverse_8_fast(bit_lib_get_bits(
|
||||
protocol->encoded_data,
|
||||
PAC_STANLEY_DATA_START_INDEX + (PAC_STANLEY_BYTE_LENGTH * idx),
|
||||
8));
|
||||
stripped_byte = byte & 0x7F; // discard the parity bit
|
||||
if(bit_lib_test_parity_32(stripped_byte, BitLibParityOdd) != (byte & 0x80) >> 7) {
|
||||
return false;
|
||||
}
|
||||
if(stripped_byte != checksum) return false;
|
||||
if(idx < 8) checksum ^= stripped_byte;
|
||||
}
|
||||
if(stripped_byte != checksum) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -201,9 +201,9 @@ bool protocol_pac_stanley_write_data(ProtocolPACStanley* protocol, void* data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, string_t result) {
|
||||
void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, FuriString* result) {
|
||||
uint8_t* data = protocol->data;
|
||||
string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]);
|
||||
furi_string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
|
||||
const ProtocolBase protocol_pac_stanley = {
|
||||
|
||||
@@ -136,26 +136,26 @@ LevelDuration protocol_paradox_encoder_yield(ProtocolParadox* protocol) {
|
||||
return level_duration_make(level, duration);
|
||||
};
|
||||
|
||||
void protocol_paradox_render_data(ProtocolParadox* protocol, string_t result) {
|
||||
void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) {
|
||||
uint8_t* decoded_data = protocol->data;
|
||||
uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8);
|
||||
uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16);
|
||||
|
||||
string_cat_printf(result, "Facility: %u\r\n", fc);
|
||||
string_cat_printf(result, "Card: %lu\r\n", card_id);
|
||||
string_cat_printf(result, "Data: ");
|
||||
furi_string_cat_printf(result, "Facility: %u\r\n", fc);
|
||||
furi_string_cat_printf(result, "Card: %u\r\n", card_id);
|
||||
furi_string_cat_printf(result, "Data: ");
|
||||
for(size_t i = 0; i < PARADOX_DECODED_DATA_SIZE; i++) {
|
||||
string_cat_printf(result, "%02X", decoded_data[i]);
|
||||
furi_string_cat_printf(result, "%02X", decoded_data[i]);
|
||||
}
|
||||
};
|
||||
|
||||
void protocol_paradox_render_brief_data(ProtocolParadox* protocol, string_t result) {
|
||||
void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* result) {
|
||||
uint8_t* decoded_data = protocol->data;
|
||||
|
||||
uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8);
|
||||
uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16);
|
||||
|
||||
string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id);
|
||||
furi_string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id);
|
||||
};
|
||||
|
||||
bool protocol_paradox_write_data(ProtocolParadox* protocol, void* data) {
|
||||
|
||||
@@ -221,6 +221,7 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) {
|
||||
|
||||
// Correct protocol data by redecoding
|
||||
protocol_pyramid_encode(protocol);
|
||||
bit_lib_remove_bit_every_nth(protocol->encoded_data, 8, 15 * 8, 8);
|
||||
protocol_pyramid_decode(protocol);
|
||||
|
||||
protocol_pyramid_encoder_start(protocol);
|
||||
@@ -238,11 +239,11 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_pyramid_render_data(ProtocolPyramid* protocol, string_t result) {
|
||||
void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) {
|
||||
uint8_t* decoded_data = protocol->data;
|
||||
uint8_t format_length = decoded_data[0];
|
||||
|
||||
string_cat_printf(result, "Format: 26\r\n", format_length);
|
||||
furi_string_cat_printf(result, "Format: %d\r\n", format_length);
|
||||
if(format_length == 26) {
|
||||
uint8_t facility;
|
||||
bit_lib_copy_bits(&facility, 0, 8, decoded_data, 8);
|
||||
@@ -250,9 +251,9 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, string_t result) {
|
||||
uint16_t card_id;
|
||||
bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 16);
|
||||
bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 24);
|
||||
string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id);
|
||||
furi_string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id);
|
||||
} else {
|
||||
string_cat_printf(result, "Data: unknown");
|
||||
furi_string_cat_printf(result, "Data: unknown");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -175,9 +175,9 @@ bool protocol_viking_write_data(ProtocolViking* protocol, void* data) {
|
||||
return result;
|
||||
};
|
||||
|
||||
void protocol_viking_render_data(ProtocolViking* protocol, string_t result) {
|
||||
void protocol_viking_render_data(ProtocolViking* protocol, FuriString* result) {
|
||||
uint32_t id = bit_lib_get_bits_32(protocol->data, 0, 32);
|
||||
string_printf(result, "ID: %08lX\r\n", id);
|
||||
furi_string_printf(result, "ID: %08lX\r\n", id);
|
||||
};
|
||||
|
||||
const ProtocolBase protocol_viking = {
|
||||
|
||||
@@ -66,19 +66,28 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) {
|
||||
}
|
||||
|
||||
// Read total amount of keys
|
||||
string_t next_line;
|
||||
string_init(next_line);
|
||||
FuriString* next_line;
|
||||
next_line = furi_string_alloc();
|
||||
while(true) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(string_get_char(next_line, 0) == '#') continue;
|
||||
if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(!stream_read_line(dict->stream, next_line)) {
|
||||
FURI_LOG_T(TAG, "No keys left in dict");
|
||||
break;
|
||||
}
|
||||
furi_string_trim(next_line);
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"Read line: %s, len: %d",
|
||||
furi_string_get_cstr(next_line),
|
||||
furi_string_size(next_line));
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN - 1) continue;
|
||||
dict->total_keys++;
|
||||
}
|
||||
string_clear(next_line);
|
||||
furi_string_free(next_line);
|
||||
stream_rewind(dict->stream);
|
||||
|
||||
dict_loaded = true;
|
||||
FURI_LOG_I(TAG, "Loaded dictionary with %d keys", dict->total_keys);
|
||||
FURI_LOG_I(TAG, "Loaded dictionary with %ld keys", dict->total_keys);
|
||||
} while(false);
|
||||
|
||||
if(!dict_loaded) {
|
||||
@@ -99,20 +108,20 @@ void mf_classic_dict_free(MfClassicDict* dict) {
|
||||
free(dict);
|
||||
}
|
||||
|
||||
static void mf_classic_dict_int_to_str(uint8_t* key_int, string_t key_str) {
|
||||
string_reset(key_str);
|
||||
static void mf_classic_dict_int_to_str(uint8_t* key_int, FuriString* key_str) {
|
||||
furi_string_reset(key_str);
|
||||
for(size_t i = 0; i < 6; i++) {
|
||||
string_cat_printf(key_str, "%02X", key_int[i]);
|
||||
furi_string_cat_printf(key_str, "%02X", key_int[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void mf_classic_dict_str_to_int(string_t key_str, uint64_t* key_int) {
|
||||
static void mf_classic_dict_str_to_int(FuriString* key_str, uint64_t* key_int) {
|
||||
uint8_t key_byte_tmp;
|
||||
|
||||
*key_int = 0ULL;
|
||||
for(uint8_t i = 0; i < 12; i += 2) {
|
||||
args_char_to_hex(
|
||||
string_get_char(key_str, i), string_get_char(key_str, i + 1), &key_byte_tmp);
|
||||
furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp);
|
||||
*key_int |= (uint64_t)key_byte_tmp << 8 * (5 - i / 2);
|
||||
}
|
||||
}
|
||||
@@ -130,17 +139,17 @@ bool mf_classic_dict_rewind(MfClassicDict* dict) {
|
||||
return stream_rewind(dict->stream);
|
||||
}
|
||||
|
||||
bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t key) {
|
||||
bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
bool key_read = false;
|
||||
string_reset(key);
|
||||
furi_string_reset(key);
|
||||
while(!key_read) {
|
||||
if(!stream_read_line(dict->stream, key)) break;
|
||||
if(string_get_char(key, 0) == '#') continue;
|
||||
if(string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
string_left(key, 12);
|
||||
if(furi_string_get_char(key, 0) == '#') continue;
|
||||
if(furi_string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
furi_string_left(key, 12);
|
||||
key_read = true;
|
||||
}
|
||||
|
||||
@@ -151,53 +160,53 @@ bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t temp_key;
|
||||
string_init(temp_key);
|
||||
FuriString* temp_key;
|
||||
temp_key = furi_string_alloc();
|
||||
bool key_read = mf_classic_dict_get_next_key_str(dict, temp_key);
|
||||
if(key_read) {
|
||||
mf_classic_dict_str_to_int(temp_key, key);
|
||||
}
|
||||
string_clear(temp_key);
|
||||
furi_string_free(temp_key);
|
||||
return key_read;
|
||||
}
|
||||
|
||||
bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, string_t key) {
|
||||
bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t next_line;
|
||||
string_init(next_line);
|
||||
FuriString* next_line;
|
||||
next_line = furi_string_alloc();
|
||||
|
||||
bool key_found = false;
|
||||
stream_rewind(dict->stream);
|
||||
while(!key_found) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(string_get_char(next_line, 0) == '#') continue;
|
||||
if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
string_left(next_line, 12);
|
||||
if(!string_equal_p(key, next_line)) continue;
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
furi_string_left(next_line, 12);
|
||||
if(!furi_string_equal(key, next_line)) continue;
|
||||
key_found = true;
|
||||
}
|
||||
|
||||
string_clear(next_line);
|
||||
furi_string_free(next_line);
|
||||
return key_found;
|
||||
}
|
||||
|
||||
bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key) {
|
||||
string_t temp_key;
|
||||
FuriString* temp_key;
|
||||
|
||||
string_init(temp_key);
|
||||
temp_key = furi_string_alloc();
|
||||
mf_classic_dict_int_to_str(key, temp_key);
|
||||
bool key_found = mf_classic_dict_is_key_present_str(dict, temp_key);
|
||||
string_clear(temp_key);
|
||||
furi_string_free(temp_key);
|
||||
return key_found;
|
||||
}
|
||||
|
||||
bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key) {
|
||||
bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_cat_printf(key, "\n");
|
||||
furi_string_cat_printf(key, "\n");
|
||||
|
||||
bool key_added = false;
|
||||
do {
|
||||
@@ -207,7 +216,7 @@ bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key) {
|
||||
key_added = true;
|
||||
} while(false);
|
||||
|
||||
string_left(key, 12);
|
||||
furi_string_left(key, 12);
|
||||
return key_added;
|
||||
}
|
||||
|
||||
@@ -215,35 +224,35 @@ bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t temp_key;
|
||||
string_init(temp_key);
|
||||
FuriString* temp_key;
|
||||
temp_key = furi_string_alloc();
|
||||
mf_classic_dict_int_to_str(key, temp_key);
|
||||
bool key_added = mf_classic_dict_add_key_str(dict, temp_key);
|
||||
|
||||
string_clear(temp_key);
|
||||
furi_string_free(temp_key);
|
||||
return key_added;
|
||||
}
|
||||
|
||||
bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, string_t key, uint32_t target) {
|
||||
bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t next_line;
|
||||
FuriString* next_line;
|
||||
uint32_t index = 0;
|
||||
string_init(next_line);
|
||||
string_reset(key);
|
||||
next_line = furi_string_alloc();
|
||||
furi_string_reset(key);
|
||||
|
||||
bool key_found = false;
|
||||
while(!key_found) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(string_get_char(next_line, 0) == '#') continue;
|
||||
if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(index++ != target) continue;
|
||||
string_set_n(key, next_line, 0, 12);
|
||||
furi_string_set_n(key, next_line, 0, 12);
|
||||
key_found = true;
|
||||
}
|
||||
|
||||
string_clear(next_line);
|
||||
furi_string_free(next_line);
|
||||
return key_found;
|
||||
}
|
||||
|
||||
@@ -251,37 +260,37 @@ bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t temp_key;
|
||||
string_init(temp_key);
|
||||
FuriString* temp_key;
|
||||
temp_key = furi_string_alloc();
|
||||
bool key_found = mf_classic_dict_get_key_at_index_str(dict, temp_key, target);
|
||||
if(key_found) {
|
||||
mf_classic_dict_str_to_int(temp_key, key);
|
||||
}
|
||||
string_clear(temp_key);
|
||||
furi_string_free(temp_key);
|
||||
return key_found;
|
||||
}
|
||||
|
||||
bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t key, uint32_t* target) {
|
||||
bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t next_line;
|
||||
string_init(next_line);
|
||||
FuriString* next_line;
|
||||
next_line = furi_string_alloc();
|
||||
|
||||
bool key_found = false;
|
||||
uint32_t index = 0;
|
||||
stream_rewind(dict->stream);
|
||||
while(!key_found) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(string_get_char(next_line, 0) == '#') continue;
|
||||
if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
string_left(next_line, 12);
|
||||
if(!string_equal_p(key, next_line)) continue;
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
furi_string_left(next_line, 12);
|
||||
if(!furi_string_equal(key, next_line)) continue;
|
||||
key_found = true;
|
||||
*target = index;
|
||||
}
|
||||
|
||||
string_clear(next_line);
|
||||
furi_string_free(next_line);
|
||||
return key_found;
|
||||
}
|
||||
|
||||
@@ -289,12 +298,12 @@ bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* tar
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t temp_key;
|
||||
string_init(temp_key);
|
||||
FuriString* temp_key;
|
||||
temp_key = furi_string_alloc();
|
||||
mf_classic_dict_int_to_str(key, temp_key);
|
||||
bool key_found = mf_classic_dict_find_index_str(dict, temp_key, target);
|
||||
|
||||
string_clear(temp_key);
|
||||
furi_string_free(temp_key);
|
||||
return key_found;
|
||||
}
|
||||
|
||||
@@ -302,15 +311,15 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) {
|
||||
furi_assert(dict);
|
||||
furi_assert(dict->stream);
|
||||
|
||||
string_t next_line;
|
||||
string_init(next_line);
|
||||
FuriString* next_line;
|
||||
next_line = furi_string_alloc();
|
||||
uint32_t index = 0;
|
||||
|
||||
bool key_removed = false;
|
||||
while(!key_removed) {
|
||||
if(!stream_read_line(dict->stream, next_line)) break;
|
||||
if(string_get_char(next_line, 0) == '#') continue;
|
||||
if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(furi_string_get_char(next_line, 0) == '#') continue;
|
||||
if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
|
||||
if(index++ != target) continue;
|
||||
stream_seek(dict->stream, -NFC_MF_CLASSIC_KEY_LEN, StreamOffsetFromCurrent);
|
||||
if(!stream_delete(dict->stream, NFC_MF_CLASSIC_KEY_LEN)) break;
|
||||
@@ -318,6 +327,6 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) {
|
||||
key_removed = true;
|
||||
}
|
||||
|
||||
string_clear(next_line);
|
||||
furi_string_free(next_line);
|
||||
return key_removed;
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ bool mf_classic_dict_rewind(MfClassicDict* dict);
|
||||
|
||||
bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key);
|
||||
|
||||
bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, string_t key);
|
||||
bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key);
|
||||
|
||||
bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key);
|
||||
|
||||
bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t key);
|
||||
bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key);
|
||||
|
||||
/** Get key at target offset as uint64_t
|
||||
*
|
||||
@@ -72,7 +72,7 @@ bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, string_t key, uint32_t target);
|
||||
bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target);
|
||||
|
||||
bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key);
|
||||
|
||||
@@ -83,11 +83,11 @@ bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key);
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key);
|
||||
bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key);
|
||||
|
||||
bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target);
|
||||
|
||||
bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t key, uint32_t* target);
|
||||
bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target);
|
||||
|
||||
/** Delete key at target offset
|
||||
*
|
||||
|
||||
+11
-13
@@ -91,10 +91,8 @@ void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback,
|
||||
}
|
||||
|
||||
static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) {
|
||||
string_t str;
|
||||
string_init_printf(
|
||||
str,
|
||||
"Sector %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n",
|
||||
FuriString* str = furi_string_alloc_printf(
|
||||
"Sec %d key %c cuid %08lx nt0 %08lx nr0 %08lx ar0 %08lx nt1 %08lx nr1 %08lx ar1 %08lx\n",
|
||||
params->sector,
|
||||
params->key == MfClassicKeyA ? 'A' : 'B',
|
||||
params->cuid,
|
||||
@@ -105,7 +103,7 @@ static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) {
|
||||
params->nr1,
|
||||
params->ar1);
|
||||
bool write_success = stream_write_string(instance->file_stream, str);
|
||||
string_clear(str);
|
||||
furi_string_free(str);
|
||||
return write_success;
|
||||
}
|
||||
|
||||
@@ -199,14 +197,14 @@ void mfkey32_process_data(
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t mfkey32_get_auth_sectors(string_t data_str) {
|
||||
uint16_t mfkey32_get_auth_sectors(FuriString* data_str) {
|
||||
furi_assert(data_str);
|
||||
|
||||
uint16_t nonces_num = 0;
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
Stream* file_stream = buffered_file_stream_alloc(storage);
|
||||
string_t temp_str;
|
||||
string_init(temp_str);
|
||||
FuriString* temp_str;
|
||||
temp_str = furi_string_alloc();
|
||||
|
||||
do {
|
||||
if(!buffered_file_stream_open(
|
||||
@@ -214,17 +212,17 @@ uint16_t mfkey32_get_auth_sectors(string_t data_str) {
|
||||
break;
|
||||
while(true) {
|
||||
if(!stream_read_line(file_stream, temp_str)) break;
|
||||
size_t uid_pos = string_search_str(temp_str, "cuid");
|
||||
string_left(temp_str, uid_pos);
|
||||
string_push_back(temp_str, '\n');
|
||||
string_cat(data_str, temp_str);
|
||||
size_t uid_pos = furi_string_search(temp_str, "cuid");
|
||||
furi_string_left(temp_str, uid_pos);
|
||||
furi_string_push_back(temp_str, '\n');
|
||||
furi_string_cat(data_str, temp_str);
|
||||
nonces_num++;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
buffered_file_stream_close(file_stream);
|
||||
stream_free(file_stream);
|
||||
string_clear(temp_str);
|
||||
furi_string_free(temp_str);
|
||||
|
||||
return nonces_num;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <lib/nfc/protocols/mifare_classic.h>
|
||||
#include <m-string.h>
|
||||
|
||||
typedef struct Mfkey32 Mfkey32;
|
||||
|
||||
@@ -24,4 +23,4 @@ void mfkey32_process_data(
|
||||
|
||||
void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context);
|
||||
|
||||
uint16_t mfkey32_get_auth_sectors(string_t string);
|
||||
uint16_t mfkey32_get_auth_sectors(FuriString* string);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "nfc_debug_log.h"
|
||||
|
||||
#include <m-string.h>
|
||||
#include <storage/storage.h>
|
||||
#include <stream/buffered_file_stream.h>
|
||||
|
||||
@@ -10,7 +9,7 @@
|
||||
|
||||
struct NfcDebugLog {
|
||||
Stream* file_stream;
|
||||
string_t data_str;
|
||||
FuriString* data_str;
|
||||
};
|
||||
|
||||
NfcDebugLog* nfc_debug_log_alloc() {
|
||||
@@ -30,7 +29,7 @@ NfcDebugLog* nfc_debug_log_alloc() {
|
||||
free(instance);
|
||||
instance = NULL;
|
||||
} else {
|
||||
string_init(instance->data_str);
|
||||
instance->data_str = furi_string_alloc();
|
||||
}
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
@@ -44,7 +43,7 @@ void nfc_debug_log_free(NfcDebugLog* instance) {
|
||||
|
||||
buffered_file_stream_close(instance->file_stream);
|
||||
stream_free(instance->file_stream);
|
||||
string_clear(instance->data_str);
|
||||
furi_string_free(instance->data_str);
|
||||
|
||||
free(instance);
|
||||
}
|
||||
@@ -61,12 +60,12 @@ void nfc_debug_log_process_data(
|
||||
furi_assert(data);
|
||||
UNUSED(crc_dropped);
|
||||
|
||||
string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T');
|
||||
furi_string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T');
|
||||
uint16_t data_len = len;
|
||||
for(size_t i = 0; i < data_len; i++) {
|
||||
string_cat_printf(instance->data_str, " %02x", data[i]);
|
||||
furi_string_cat_printf(instance->data_str, " %02x", data[i]);
|
||||
}
|
||||
string_push_back(instance->data_str, '\n');
|
||||
furi_string_push_back(instance->data_str, '\n');
|
||||
|
||||
stream_write_string(instance->file_stream, instance->data_str);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "reader_analyzer.h"
|
||||
#include <stream_buffer.h>
|
||||
#include <lib/nfc/protocols/nfc_util.h>
|
||||
#include <lib/nfc/protocols/mifare_classic.h>
|
||||
#include <m-array.h>
|
||||
@@ -26,7 +25,7 @@ struct ReaderAnalyzer {
|
||||
FuriHalNfcDevData nfc_data;
|
||||
|
||||
bool alive;
|
||||
StreamBufferHandle_t stream;
|
||||
FuriStreamBuffer* stream;
|
||||
FuriThread* thread;
|
||||
|
||||
ReaderAnalyzerParseDataCallback callback;
|
||||
@@ -86,8 +85,8 @@ int32_t reader_analyzer_thread(void* context) {
|
||||
ReaderAnalyzer* reader_analyzer = context;
|
||||
uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {};
|
||||
|
||||
while(reader_analyzer->alive || !xStreamBufferIsEmpty(reader_analyzer->stream)) {
|
||||
size_t ret = xStreamBufferReceive(
|
||||
while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) {
|
||||
size_t ret = furi_stream_buffer_receive(
|
||||
reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50);
|
||||
if(ret) {
|
||||
reader_analyzer_parse(reader_analyzer, buffer, ret);
|
||||
@@ -103,7 +102,7 @@ ReaderAnalyzer* reader_analyzer_alloc() {
|
||||
instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic];
|
||||
instance->alive = false;
|
||||
instance->stream =
|
||||
xStreamBufferCreate(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader));
|
||||
furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader));
|
||||
|
||||
instance->thread = furi_thread_alloc();
|
||||
furi_thread_set_name(instance->thread, "ReaderAnalyzerWorker");
|
||||
@@ -129,7 +128,7 @@ static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) {
|
||||
void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) {
|
||||
furi_assert(instance);
|
||||
|
||||
xStreamBufferReset(instance->stream);
|
||||
furi_stream_buffer_reset(instance->stream);
|
||||
if(mode & ReaderAnalyzerModeDebugLog) {
|
||||
instance->debug_log = nfc_debug_log_alloc();
|
||||
}
|
||||
@@ -171,7 +170,7 @@ void reader_analyzer_free(ReaderAnalyzer* instance) {
|
||||
|
||||
reader_analyzer_stop(instance);
|
||||
furi_thread_free(instance->thread);
|
||||
vStreamBufferDelete(instance->stream);
|
||||
furi_stream_buffer_free(instance->stream);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
@@ -215,12 +214,12 @@ static void reader_analyzer_write(
|
||||
ReaderAnalyzerHeader header = {
|
||||
.reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len};
|
||||
size_t data_sent = 0;
|
||||
data_sent = xStreamBufferSend(
|
||||
data_sent = furi_stream_buffer_send(
|
||||
instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever);
|
||||
if(data_sent != sizeof(ReaderAnalyzerHeader)) {
|
||||
FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, sizeof(ReaderAnalyzerHeader));
|
||||
}
|
||||
data_sent = xStreamBufferSend(instance->stream, data, len, FuriWaitForever);
|
||||
data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever);
|
||||
if(data_sent != len) {
|
||||
FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, len);
|
||||
}
|
||||
|
||||
+296
-270
File diff suppressed because it is too large
Load Diff
@@ -63,7 +63,7 @@ typedef struct {
|
||||
MfClassicData mf_classic_data;
|
||||
MifareDesfireData mf_df_data;
|
||||
};
|
||||
string_t parsed_data;
|
||||
FuriString* parsed_data;
|
||||
} NfcDeviceData;
|
||||
|
||||
typedef struct {
|
||||
@@ -71,7 +71,7 @@ typedef struct {
|
||||
DialogsApp* dialogs;
|
||||
NfcDeviceData dev_data;
|
||||
char dev_name[NFC_DEV_NAME_MAX_LEN + 1];
|
||||
string_t load_path;
|
||||
FuriString* load_path;
|
||||
NfcDeviceSaveFormat format;
|
||||
bool shadow_file_exist;
|
||||
|
||||
|
||||
+75
-2
@@ -502,6 +502,54 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) {
|
||||
}
|
||||
}
|
||||
|
||||
static void nfc_worker_mf_classic_key_attack(
|
||||
NfcWorker* nfc_worker,
|
||||
uint64_t key,
|
||||
FuriHalNfcTxRxContext* tx_rx,
|
||||
uint16_t start_sector) {
|
||||
furi_assert(nfc_worker);
|
||||
|
||||
MfClassicData* data = &nfc_worker->dev_data->mf_classic_data;
|
||||
uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type);
|
||||
|
||||
furi_assert(start_sector < total_sectors);
|
||||
|
||||
// Check every sector's A and B keys with the given key
|
||||
for(size_t i = start_sector; i < total_sectors; i++) {
|
||||
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
||||
if(mf_classic_is_sector_read(data, i)) continue;
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"Trying A key for sector %d, key: %04lx%08lx",
|
||||
i,
|
||||
(uint32_t)(key >> 32),
|
||||
(uint32_t)key);
|
||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"Trying B key for sector %d, key: %04lx%08lx",
|
||||
i,
|
||||
(uint32_t)(key >> 32),
|
||||
(uint32_t)key);
|
||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
}
|
||||
}
|
||||
if(mf_classic_is_sector_read(data, i)) continue;
|
||||
mf_classic_read_sector(tx_rx, data, i);
|
||||
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
furi_assert(nfc_worker);
|
||||
furi_assert(nfc_worker->callback);
|
||||
@@ -523,7 +571,8 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
return;
|
||||
}
|
||||
|
||||
FURI_LOG_D(TAG, "Start Dictionary attack, Key Count %d", mf_classic_dict_get_total_keys(dict));
|
||||
FURI_LOG_D(
|
||||
TAG, "Start Dictionary attack, Key Count %ld", mf_classic_dict_get_total_keys(dict));
|
||||
for(size_t i = 0; i < total_sectors; i++) {
|
||||
FURI_LOG_I(TAG, "Sector %d", i);
|
||||
nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context);
|
||||
@@ -533,6 +582,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
uint16_t key_index = 0;
|
||||
while(mf_classic_dict_get_next_key(dict, &key)) {
|
||||
FURI_LOG_T(TAG, "Key %d", key_index);
|
||||
if(++key_index % NFC_DICT_KEY_BATCH_SIZE == 0) {
|
||||
nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context);
|
||||
}
|
||||
@@ -554,15 +604,19 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
||||
is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA);
|
||||
if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyA)) {
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
||||
}
|
||||
furi_hal_nfc_sleep();
|
||||
}
|
||||
if(!is_key_b_found) {
|
||||
is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
||||
if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyB)) {
|
||||
FURI_LOG_D(TAG, "Key found");
|
||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
||||
}
|
||||
}
|
||||
if(is_key_a_found && is_key_b_found) break;
|
||||
@@ -696,7 +750,8 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void*
|
||||
furi_assert(context);
|
||||
NfcWorker* nfc_worker = context;
|
||||
|
||||
if(event == ReaderAnalyzerEventMfkeyCollected) {
|
||||
if((nfc_worker->state == NfcWorkerStateAnalyzeReader) &&
|
||||
(event == ReaderAnalyzerEventMfkeyCollected)) {
|
||||
if(nfc_worker->callback) {
|
||||
nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context);
|
||||
}
|
||||
@@ -704,6 +759,9 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void*
|
||||
}
|
||||
|
||||
void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
|
||||
furi_assert(nfc_worker);
|
||||
furi_assert(nfc_worker->callback);
|
||||
|
||||
FuriHalNfcTxRxContext tx_rx = {};
|
||||
|
||||
ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer;
|
||||
@@ -722,17 +780,32 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
|
||||
rfal_platform_spi_acquire();
|
||||
|
||||
FURI_LOG_D(TAG, "Start reader analyzer");
|
||||
|
||||
uint8_t reader_no_data_received_cnt = 0;
|
||||
bool reader_no_data_notified = true;
|
||||
|
||||
while(nfc_worker->state == NfcWorkerStateAnalyzeReader) {
|
||||
furi_hal_nfc_stop_cmd();
|
||||
furi_delay_ms(5);
|
||||
furi_hal_nfc_listen_start(nfc_data);
|
||||
if(furi_hal_nfc_listen_rx(&tx_rx, 300)) {
|
||||
if(reader_no_data_notified) {
|
||||
nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context);
|
||||
}
|
||||
reader_no_data_received_cnt = 0;
|
||||
reader_no_data_notified = false;
|
||||
NfcProtocol protocol =
|
||||
reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8);
|
||||
if(protocol == NfcDeviceProtocolMifareClassic) {
|
||||
mf_classic_emulator(&emulator, &tx_rx);
|
||||
}
|
||||
} else {
|
||||
reader_no_data_received_cnt++;
|
||||
if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) {
|
||||
nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context);
|
||||
reader_no_data_received_cnt = 0;
|
||||
reader_no_data_notified = true;
|
||||
}
|
||||
FURI_LOG_D(TAG, "No data from reader");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@ typedef enum {
|
||||
NfcWorkerEventFoundKeyB,
|
||||
|
||||
// Detect Reader events
|
||||
NfcWorkerEventDetectReaderDetected,
|
||||
NfcWorkerEventDetectReaderLost,
|
||||
NfcWorkerEventDetectReaderMfkeyCollected,
|
||||
|
||||
// Mifare Ultralight events
|
||||
|
||||
@@ -107,7 +107,7 @@ bool all_in_one_parser_parse(NfcDeviceData* dev_data) {
|
||||
dev_data->mf_ul_data.data[4 * 4 + 5] << 4 | (dev_data->mf_ul_data.data[4 * 4 + 6] >> 4);
|
||||
|
||||
// Format string for rides count
|
||||
string_printf(
|
||||
dev_data->parsed_data, "\e#All-In-One\nNumber: %u\nRides left: %u", serial, ride_count);
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data, "\e#All-In-One\nNumber: %lu\nRides left: %u", serial, ride_count);
|
||||
return true;
|
||||
}
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "../nfc_worker.h"
|
||||
#include "../nfc_device.h"
|
||||
|
||||
#include <m-string.h>
|
||||
|
||||
typedef enum {
|
||||
NfcSupportedCardTypePlantain,
|
||||
NfcSupportedCardTypeTroika,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "nfc_supported_card.h"
|
||||
#include "plantain_parser.h" // For luhn and string_push_uint64
|
||||
|
||||
#include <gui/modules/widget.h>
|
||||
#include <nfc_worker_i.h>
|
||||
@@ -118,36 +117,25 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) {
|
||||
card_number = (card_number << 8) | card_number_arr[i];
|
||||
}
|
||||
// Convert card number to string
|
||||
string_t card_number_str;
|
||||
string_init(card_number_str);
|
||||
FuriString* card_number_str;
|
||||
card_number_str = furi_string_alloc();
|
||||
// Should look like "361301047292848684"
|
||||
// %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead
|
||||
string_push_uint64(card_number, card_number_str);
|
||||
furi_string_printf(card_number_str, "%llu", card_number);
|
||||
// Add suffix with luhn checksum (1 digit) to the card number string
|
||||
string_t card_number_suffix;
|
||||
string_init(card_number_suffix);
|
||||
FuriString* card_number_suffix;
|
||||
card_number_suffix = furi_string_alloc();
|
||||
|
||||
// The number to calculate the checksum on doesn't fit into uint64_t, idk
|
||||
//uint8_t luhn_checksum = plantain_calculate_luhn(card_number);
|
||||
|
||||
// // Convert luhn checksum to string
|
||||
// string_t luhn_checksum_str;
|
||||
// string_init(luhn_checksum_str);
|
||||
// string_push_uint64(luhn_checksum, luhn_checksum_str);
|
||||
|
||||
string_cat_printf(card_number_suffix, "-");
|
||||
// FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum);
|
||||
string_cat_printf(card_number_str, string_get_cstr(card_number_suffix));
|
||||
furi_string_cat_printf(card_number_suffix, "-");
|
||||
furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix));
|
||||
// Free all not needed strings
|
||||
string_clear(card_number_suffix);
|
||||
// string_clear(luhn_checksum_str);
|
||||
furi_string_free(card_number_suffix);
|
||||
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data,
|
||||
"\e#Plantain\nN:%s\nBalance:%d\n",
|
||||
string_get_cstr(card_number_str),
|
||||
"\e#Plantain\nN:%s\nBalance:%ld\n",
|
||||
furi_string_get_cstr(card_number_str),
|
||||
balance);
|
||||
string_clear(card_number_str);
|
||||
furi_string_free(card_number_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -55,28 +55,6 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
|
||||
return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16;
|
||||
}
|
||||
|
||||
void string_push_uint64(uint64_t input, string_t output) {
|
||||
const uint8_t base = 10;
|
||||
|
||||
do {
|
||||
char c = input % base;
|
||||
input /= base;
|
||||
|
||||
if(c < 10)
|
||||
c += '0';
|
||||
else
|
||||
c += 'A' - 10;
|
||||
string_push_back(output, c);
|
||||
} while(input);
|
||||
|
||||
// reverse string
|
||||
for(uint8_t i = 0; i < string_size(output) / 2; i++) {
|
||||
char c = string_get_char(output, i);
|
||||
string_set_char(output, i, string_get_char(output, string_size(output) - i - 1));
|
||||
string_set_char(output, string_size(output) - i - 1, c);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t plantain_calculate_luhn(uint64_t number) {
|
||||
// No.
|
||||
UNUSED(number);
|
||||
@@ -112,36 +90,25 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) {
|
||||
card_number = (card_number << 8) | card_number_arr[i];
|
||||
}
|
||||
// Convert card number to string
|
||||
string_t card_number_str;
|
||||
string_init(card_number_str);
|
||||
FuriString* card_number_str;
|
||||
card_number_str = furi_string_alloc();
|
||||
// Should look like "361301047292848684"
|
||||
// %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead
|
||||
string_push_uint64(card_number, card_number_str);
|
||||
furi_string_printf(card_number_str, "%llu", card_number);
|
||||
// Add suffix with luhn checksum (1 digit) to the card number string
|
||||
string_t card_number_suffix;
|
||||
string_init(card_number_suffix);
|
||||
FuriString* card_number_suffix;
|
||||
card_number_suffix = furi_string_alloc();
|
||||
|
||||
// The number to calculate the checksum on doesn't fit into uint64_t, idk
|
||||
//uint8_t luhn_checksum = plantain_calculate_luhn(card_number);
|
||||
|
||||
// // Convert luhn checksum to string
|
||||
// string_t luhn_checksum_str;
|
||||
// string_init(luhn_checksum_str);
|
||||
// string_push_uint64(luhn_checksum, luhn_checksum_str);
|
||||
|
||||
string_cat_printf(card_number_suffix, "-");
|
||||
// FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum);
|
||||
string_cat_printf(card_number_str, string_get_cstr(card_number_suffix));
|
||||
furi_string_cat_printf(card_number_suffix, "-");
|
||||
furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix));
|
||||
// Free all not needed strings
|
||||
string_clear(card_number_suffix);
|
||||
// string_clear(luhn_checksum_str);
|
||||
furi_string_free(card_number_suffix);
|
||||
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data,
|
||||
"\e#Plantain\nN:%s\nBalance:%d\n",
|
||||
string_get_cstr(card_number_str),
|
||||
"\e#Plantain\nN:%s\nBalance:%ld\n",
|
||||
furi_string_get_cstr(card_number_str),
|
||||
balance);
|
||||
string_clear(card_number_str);
|
||||
furi_string_free(card_number_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,4 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx);
|
||||
|
||||
bool plantain_parser_parse(NfcDeviceData* dev_data);
|
||||
|
||||
void string_push_uint64(uint64_t input, string_t output);
|
||||
|
||||
uint8_t plantain_calculate_luhn(uint64_t number);
|
||||
|
||||
@@ -98,7 +98,8 @@ bool troika_4k_parser_parse(NfcDeviceData* dev_data) {
|
||||
}
|
||||
number >>= 4;
|
||||
|
||||
string_printf(dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance);
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ bool troika_parser_parse(NfcDeviceData* dev_data) {
|
||||
}
|
||||
number >>= 4;
|
||||
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance);
|
||||
troika_parsed = true;
|
||||
} while(false);
|
||||
|
||||
@@ -118,29 +118,18 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) {
|
||||
card_number = (card_number << 8) | card_number_arr[i];
|
||||
}
|
||||
// Convert card number to string
|
||||
string_t card_number_str;
|
||||
string_init(card_number_str);
|
||||
FuriString* card_number_str;
|
||||
card_number_str = furi_string_alloc();
|
||||
// Should look like "361301047292848684"
|
||||
// %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead
|
||||
string_push_uint64(card_number, card_number_str);
|
||||
furi_string_printf(card_number_str, "%llu", card_number);
|
||||
// Add suffix with luhn checksum (1 digit) to the card number string
|
||||
string_t card_number_suffix;
|
||||
string_init(card_number_suffix);
|
||||
FuriString* card_number_suffix;
|
||||
card_number_suffix = furi_string_alloc();
|
||||
|
||||
// The number to calculate the checksum on doesn't fit into uint64_t, idk
|
||||
//uint8_t luhn_checksum = two_cities_calculate_luhn(card_number);
|
||||
|
||||
// // Convert luhn checksum to string
|
||||
// string_t luhn_checksum_str;
|
||||
// string_init(luhn_checksum_str);
|
||||
// string_push_uint64(luhn_checksum, luhn_checksum_str);
|
||||
|
||||
string_cat_printf(card_number_suffix, "-");
|
||||
// FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum);
|
||||
string_cat_printf(card_number_str, string_get_cstr(card_number_suffix));
|
||||
furi_string_cat_printf(card_number_suffix, "-");
|
||||
furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix));
|
||||
// Free all not needed strings
|
||||
string_clear(card_number_suffix);
|
||||
// string_clear(luhn_checksum_str);
|
||||
furi_string_free(card_number_suffix);
|
||||
|
||||
// =====
|
||||
// --PLANTAIN--
|
||||
@@ -158,14 +147,14 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) {
|
||||
}
|
||||
troika_number >>= 4;
|
||||
|
||||
string_printf(
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data,
|
||||
"\e#Troika+Plantain\nPN: %s\nPB: %d rur.\nTN: %d\nTB: %d rur.\n",
|
||||
string_get_cstr(card_number_str),
|
||||
"\e#Troika+Plantain\nPN: %s\nPB: %ld rur.\nTN: %ld\nTB: %d rur.\n",
|
||||
furi_string_get_cstr(card_number_str),
|
||||
balance,
|
||||
troika_number,
|
||||
troika_balance);
|
||||
string_clear(card_number_str);
|
||||
furi_string_free(card_number_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -847,7 +847,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
|
||||
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"%08x key%c block %d nt/nr/ar: %08x %08x %08x",
|
||||
"%08lx key%c block %d nt/nr/ar: %08lx %08lx %08lx",
|
||||
emulator->cuid,
|
||||
access_key == MfClassicKeyA ? 'A' : 'B',
|
||||
sector_trailer_block,
|
||||
@@ -858,7 +858,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
|
||||
crypto1_word(&emulator->crypto, nr, 1);
|
||||
uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0);
|
||||
if(cardRr != prng_successor(nonce, 64)) {
|
||||
FURI_LOG_T(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64));
|
||||
FURI_LOG_T(TAG, "Wrong AUTH! %08lX != %08lX", cardRr, prng_successor(nonce, 64));
|
||||
// Don't send NACK, as the tag doesn't send it
|
||||
command_processed = true;
|
||||
break;
|
||||
|
||||
@@ -42,14 +42,14 @@ void mf_df_clear(MifareDesfireData* data) {
|
||||
data->app_head = NULL;
|
||||
}
|
||||
|
||||
void mf_df_cat_data(MifareDesfireData* data, string_t out) {
|
||||
void mf_df_cat_data(MifareDesfireData* data, FuriString* out) {
|
||||
mf_df_cat_card_info(data, out);
|
||||
for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
|
||||
mf_df_cat_application(app, out);
|
||||
}
|
||||
}
|
||||
|
||||
void mf_df_cat_card_info(MifareDesfireData* data, string_t out) {
|
||||
void mf_df_cat_card_info(MifareDesfireData* data, FuriString* out) {
|
||||
mf_df_cat_version(&data->version, out);
|
||||
if(data->free_memory) {
|
||||
mf_df_cat_free_mem(data->free_memory, out);
|
||||
@@ -59,8 +59,8 @@ void mf_df_cat_card_info(MifareDesfireData* data, string_t out) {
|
||||
}
|
||||
}
|
||||
|
||||
void mf_df_cat_version(MifareDesfireVersion* version, string_t out) {
|
||||
string_cat_printf(
|
||||
void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out) {
|
||||
furi_string_cat_printf(
|
||||
out,
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
version->uid[0],
|
||||
@@ -70,7 +70,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) {
|
||||
version->uid[4],
|
||||
version->uid[5],
|
||||
version->uid[6]);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
out,
|
||||
"hw %02x type %02x sub %02x\n"
|
||||
" maj %02x min %02x\n"
|
||||
@@ -82,7 +82,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) {
|
||||
version->hw_minor,
|
||||
version->hw_storage,
|
||||
version->hw_proto);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
out,
|
||||
"sw %02x type %02x sub %02x\n"
|
||||
" maj %02x min %02x\n"
|
||||
@@ -94,7 +94,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) {
|
||||
version->sw_minor,
|
||||
version->sw_storage,
|
||||
version->sw_proto);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
out,
|
||||
"batch %02x:%02x:%02x:%02x:%02x\n"
|
||||
"week %d year %d\n",
|
||||
@@ -107,40 +107,40 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) {
|
||||
version->prod_year);
|
||||
}
|
||||
|
||||
void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out) {
|
||||
string_cat_printf(out, "freeMem %d\n", free_mem->bytes);
|
||||
void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out) {
|
||||
furi_string_cat_printf(out, "freeMem %ld\n", free_mem->bytes);
|
||||
}
|
||||
|
||||
void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out) {
|
||||
string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id);
|
||||
string_cat_printf(out, "configChangeable %d\n", ks->config_changeable);
|
||||
string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete);
|
||||
string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list);
|
||||
string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable);
|
||||
void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out) {
|
||||
furi_string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id);
|
||||
furi_string_cat_printf(out, "configChangeable %d\n", ks->config_changeable);
|
||||
furi_string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete);
|
||||
furi_string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list);
|
||||
furi_string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable);
|
||||
if(ks->flags) {
|
||||
string_cat_printf(out, "flags %d\n", ks->flags);
|
||||
furi_string_cat_printf(out, "flags %d\n", ks->flags);
|
||||
}
|
||||
string_cat_printf(out, "maxKeys %d\n", ks->max_keys);
|
||||
furi_string_cat_printf(out, "maxKeys %d\n", ks->max_keys);
|
||||
for(MifareDesfireKeyVersion* kv = ks->key_version_head; kv; kv = kv->next) {
|
||||
string_cat_printf(out, "key %d version %d\n", kv->id, kv->version);
|
||||
furi_string_cat_printf(out, "key %d version %d\n", kv->id, kv->version);
|
||||
}
|
||||
}
|
||||
|
||||
void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out) {
|
||||
string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]);
|
||||
void mf_df_cat_application_info(MifareDesfireApplication* app, FuriString* out) {
|
||||
furi_string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]);
|
||||
if(app->key_settings) {
|
||||
mf_df_cat_key_settings(app->key_settings, out);
|
||||
}
|
||||
}
|
||||
|
||||
void mf_df_cat_application(MifareDesfireApplication* app, string_t out) {
|
||||
void mf_df_cat_application(MifareDesfireApplication* app, FuriString* out) {
|
||||
mf_df_cat_application_info(app, out);
|
||||
for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
|
||||
mf_df_cat_file(file, out);
|
||||
}
|
||||
}
|
||||
|
||||
void mf_df_cat_file(MifareDesfireFile* file, string_t out) {
|
||||
void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) {
|
||||
char* type = "unknown";
|
||||
switch(file->type) {
|
||||
case MifareDesfireFileTypeStandard:
|
||||
@@ -171,9 +171,9 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) {
|
||||
comm = "enciphered";
|
||||
break;
|
||||
}
|
||||
string_cat_printf(out, "File %d\n", file->id);
|
||||
string_cat_printf(out, "%s %s\n", type, comm);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(out, "File %d\n", file->id);
|
||||
furi_string_cat_printf(out, "%s %s\n", type, comm);
|
||||
furi_string_cat_printf(
|
||||
out,
|
||||
"r %d w %d rw %d c %d\n",
|
||||
file->access_rights >> 12 & 0xF,
|
||||
@@ -186,15 +186,15 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) {
|
||||
case MifareDesfireFileTypeStandard:
|
||||
case MifareDesfireFileTypeBackup:
|
||||
size = file->settings.data.size;
|
||||
string_cat_printf(out, "size %d\n", size);
|
||||
furi_string_cat_printf(out, "size %d\n", size);
|
||||
break;
|
||||
case MifareDesfireFileTypeValue:
|
||||
size = 4;
|
||||
string_cat_printf(
|
||||
out, "lo %d hi %d\n", file->settings.value.lo_limit, file->settings.value.hi_limit);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
out, "lo %ld hi %ld\n", file->settings.value.lo_limit, file->settings.value.hi_limit);
|
||||
furi_string_cat_printf(
|
||||
out,
|
||||
"limit %d enabled %d\n",
|
||||
"limit %ld enabled %d\n",
|
||||
file->settings.value.limited_credit_value,
|
||||
file->settings.value.limited_credit_enabled);
|
||||
break;
|
||||
@@ -202,33 +202,33 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) {
|
||||
case MifareDesfireFileTypeCyclicRecord:
|
||||
size = file->settings.record.size;
|
||||
num = file->settings.record.cur;
|
||||
string_cat_printf(out, "size %d\n", size);
|
||||
string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max);
|
||||
furi_string_cat_printf(out, "size %d\n", size);
|
||||
furi_string_cat_printf(out, "num %d max %ld\n", num, file->settings.record.max);
|
||||
break;
|
||||
}
|
||||
uint8_t* data = file->contents;
|
||||
if(data) {
|
||||
for(int rec = 0; rec < num; rec++) {
|
||||
string_cat_printf(out, "record %d\n", rec);
|
||||
furi_string_cat_printf(out, "record %d\n", rec);
|
||||
for(int ch = 0; ch < size; ch += 4) {
|
||||
string_cat_printf(out, "%03x|", ch);
|
||||
furi_string_cat_printf(out, "%03x|", ch);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(ch + i < size) {
|
||||
string_cat_printf(out, "%02x ", data[rec * size + ch + i]);
|
||||
furi_string_cat_printf(out, "%02x ", data[rec * size + ch + i]);
|
||||
} else {
|
||||
string_cat_printf(out, " ");
|
||||
furi_string_cat_printf(out, " ");
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < 4 && ch + i < size; i++) {
|
||||
if(isprint(data[rec * size + ch + i])) {
|
||||
string_cat_printf(out, "%c", data[rec * size + ch + i]);
|
||||
furi_string_cat_printf(out, "%c", data[rec * size + ch + i]);
|
||||
} else {
|
||||
string_cat_printf(out, ".");
|
||||
furi_string_cat_printf(out, ".");
|
||||
}
|
||||
}
|
||||
string_cat_printf(out, "\n");
|
||||
furi_string_cat_printf(out, "\n");
|
||||
}
|
||||
string_cat_printf(out, " \n");
|
||||
furi_string_cat_printf(out, " \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <m-string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -120,14 +119,14 @@ typedef struct {
|
||||
|
||||
void mf_df_clear(MifareDesfireData* data);
|
||||
|
||||
void mf_df_cat_data(MifareDesfireData* data, string_t out);
|
||||
void mf_df_cat_card_info(MifareDesfireData* data, string_t out);
|
||||
void mf_df_cat_version(MifareDesfireVersion* version, string_t out);
|
||||
void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out);
|
||||
void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out);
|
||||
void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out);
|
||||
void mf_df_cat_application(MifareDesfireApplication* app, string_t out);
|
||||
void mf_df_cat_file(MifareDesfireFile* file, string_t out);
|
||||
void mf_df_cat_data(MifareDesfireData* data, FuriString* out);
|
||||
void mf_df_cat_card_info(MifareDesfireData* data, FuriString* out);
|
||||
void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out);
|
||||
void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out);
|
||||
void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out);
|
||||
void mf_df_cat_application_info(MifareDesfireApplication* app, FuriString* out);
|
||||
void mf_df_cat_application(MifareDesfireApplication* app, FuriString* out);
|
||||
void mf_df_cat_file(MifareDesfireFile* file, FuriString* out);
|
||||
|
||||
bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "nfc_util.h"
|
||||
#include <furi.h>
|
||||
#include "furi_hal_nfc.h"
|
||||
#include <m-string.h>
|
||||
|
||||
#define TAG "MfUltralight"
|
||||
|
||||
@@ -194,7 +193,7 @@ bool mf_ultralight_authenticate(FuriHalNfcTxRxContext* tx_rx, uint32_t key, uint
|
||||
*pack = (tx_rx->rx_data[1] << 8) | tx_rx->rx_data[0];
|
||||
}
|
||||
|
||||
FURI_LOG_I(TAG, "Auth success. Password: %08X. PACK: %04X", key, *pack);
|
||||
FURI_LOG_I(TAG, "Auth success. Password: %08lX. PACK: %04X", key, *pack);
|
||||
authenticated = true;
|
||||
} while(false);
|
||||
|
||||
@@ -1005,7 +1004,7 @@ static bool mf_ul_check_lock(MfUltralightEmulator* emulator, int16_t write_page)
|
||||
return (dynamic_lock_bytes & (1 << shift)) == 0;
|
||||
}
|
||||
|
||||
static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str) {
|
||||
static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, FuriString* str) {
|
||||
// Locals to improve readability
|
||||
uint8_t mirror_page = emulator->config->mirror_page;
|
||||
uint8_t mirror_byte = emulator->config->mirror.mirror_byte;
|
||||
@@ -1020,14 +1019,14 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str
|
||||
if(mirror_conf == MfUltralightMirrorUid) return;
|
||||
// NTAG21x has the peculiar behavior when UID+counter selected, if UID does not fit but
|
||||
// counter will fit, it will actually mirror the counter
|
||||
string_cat_str(str, " ");
|
||||
furi_string_cat(str, " ");
|
||||
} else {
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
string_cat_printf(str, "%02X", emulator->data.data[i]);
|
||||
furi_string_cat_printf(str, "%02X", emulator->data.data[i]);
|
||||
}
|
||||
// Skip BCC0
|
||||
for(int i = 4; i < 8; ++i) {
|
||||
string_cat_printf(str, "%02X", emulator->data.data[i]);
|
||||
furi_string_cat_printf(str, "%02X", emulator->data.data[i]);
|
||||
}
|
||||
uid_printed = true;
|
||||
}
|
||||
@@ -1049,9 +1048,9 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str
|
||||
if(mirror_page == last_user_page_index - 1 && mirror_byte > 2) return;
|
||||
|
||||
if(mirror_conf == MfUltralightMirrorUidCounter)
|
||||
string_cat_str(str, uid_printed ? "x" : " ");
|
||||
furi_string_cat(str, uid_printed ? "x" : " ");
|
||||
|
||||
string_cat_printf(str, "%06X", emulator->data.counter[2]);
|
||||
furi_string_cat_printf(str, "%06lX", emulator->data.counter[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1267,14 +1266,14 @@ bool mf_ul_prepare_emulation_response(
|
||||
bool reset_idle = false;
|
||||
|
||||
#ifdef FURI_DEBUG
|
||||
string_t debug_buf;
|
||||
string_init(debug_buf);
|
||||
FuriString* debug_buf;
|
||||
debug_buf = furi_string_alloc();
|
||||
for(int i = 0; i < (buff_rx_len + 7) / 8; ++i) {
|
||||
string_cat_printf(debug_buf, "%02x ", buff_rx[i]);
|
||||
furi_string_cat_printf(debug_buf, "%02x ", buff_rx[i]);
|
||||
}
|
||||
string_strim(debug_buf);
|
||||
FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, string_get_cstr(debug_buf));
|
||||
string_reset(debug_buf);
|
||||
furi_string_trim(debug_buf);
|
||||
FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, furi_string_get_cstr(debug_buf));
|
||||
furi_string_reset(debug_buf);
|
||||
#endif
|
||||
|
||||
// Check composite commands
|
||||
@@ -1328,7 +1327,7 @@ bool mf_ul_prepare_emulation_response(
|
||||
uint8_t src_page = start_page;
|
||||
uint8_t last_page_plus_one = start_page + 4;
|
||||
uint8_t pwd_page = emulator->page_num - 2;
|
||||
string_t ascii_mirror;
|
||||
FuriString* ascii_mirror = NULL;
|
||||
size_t ascii_mirror_len = 0;
|
||||
const char* ascii_mirror_cptr = NULL;
|
||||
uint8_t ascii_mirror_curr_page = 0;
|
||||
@@ -1353,10 +1352,10 @@ bool mf_ul_prepare_emulation_response(
|
||||
if(last_page_plus_one > ascii_mirror_curr_page &&
|
||||
start_page + 3 >= ascii_mirror_curr_page &&
|
||||
start_page <= ascii_mirror_curr_page + 6) {
|
||||
string_init(ascii_mirror);
|
||||
ascii_mirror = furi_string_alloc();
|
||||
mf_ul_make_ascii_mirror(emulator, ascii_mirror);
|
||||
ascii_mirror_len = string_length_u(ascii_mirror);
|
||||
ascii_mirror_cptr = string_get_cstr(ascii_mirror);
|
||||
ascii_mirror_len = furi_string_utf8_length(ascii_mirror);
|
||||
ascii_mirror_cptr = furi_string_get_cstr(ascii_mirror);
|
||||
// Move pointer to where it should be to start copying
|
||||
if(ascii_mirror_len > 0 &&
|
||||
ascii_mirror_curr_page < start_page &&
|
||||
@@ -1414,8 +1413,8 @@ bool mf_ul_prepare_emulation_response(
|
||||
++src_page;
|
||||
if(src_page >= last_page_plus_one) src_page = 0;
|
||||
}
|
||||
if(ascii_mirror_cptr != NULL) {
|
||||
string_clear(ascii_mirror);
|
||||
if(ascii_mirror != NULL) {
|
||||
furi_string_free(ascii_mirror);
|
||||
}
|
||||
*data_type = FURI_HAL_NFC_TXRX_DEFAULT;
|
||||
command_parsed = true;
|
||||
@@ -1512,12 +1511,13 @@ bool mf_ul_prepare_emulation_response(
|
||||
// Copy ASCII mirror
|
||||
// Less stringent check here, because expecting FAST_READ to
|
||||
// only be issued once rather than repeatedly
|
||||
string_t ascii_mirror;
|
||||
string_init(ascii_mirror);
|
||||
FuriString* ascii_mirror;
|
||||
ascii_mirror = furi_string_alloc();
|
||||
mf_ul_make_ascii_mirror(emulator, ascii_mirror);
|
||||
size_t ascii_mirror_len = string_length_u(ascii_mirror);
|
||||
size_t ascii_mirror_len =
|
||||
furi_string_utf8_length(ascii_mirror);
|
||||
const char* ascii_mirror_cptr =
|
||||
string_get_cstr(ascii_mirror);
|
||||
furi_string_get_cstr(ascii_mirror);
|
||||
int16_t mirror_start_offset =
|
||||
(emulator->config->mirror_page - start_page) * 4 +
|
||||
emulator->config->mirror.mirror_byte;
|
||||
@@ -1547,7 +1547,7 @@ bool mf_ul_prepare_emulation_response(
|
||||
++ascii_mirror_cptr;
|
||||
}
|
||||
}
|
||||
string_clear(ascii_mirror);
|
||||
furi_string_free(ascii_mirror);
|
||||
}
|
||||
|
||||
if(emulator->supported_features & MfUltralightSupportAuth) {
|
||||
@@ -1851,11 +1851,11 @@ bool mf_ul_prepare_emulation_response(
|
||||
} else if(*buff_tx_len > 0) {
|
||||
int count = (*buff_tx_len + 7) / 8;
|
||||
for(int i = 0; i < count; ++i) {
|
||||
string_cat_printf(debug_buf, "%02x ", buff_tx[i]);
|
||||
furi_string_cat_printf(debug_buf, "%02x ", buff_tx[i]);
|
||||
}
|
||||
string_strim(debug_buf);
|
||||
FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, string_get_cstr(debug_buf));
|
||||
string_clear(debug_buf);
|
||||
furi_string_trim(debug_buf);
|
||||
FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, furi_string_get_cstr(debug_buf));
|
||||
furi_string_free(debug_buf);
|
||||
} else {
|
||||
FURI_LOG_T(TAG, "Emu TX: HALT");
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <furi_hal.h>
|
||||
#include "ibutton_worker_i.h"
|
||||
#include "ibutton_key_command.h"
|
||||
#include <stream_buffer.h>
|
||||
|
||||
void ibutton_worker_mode_idle_start(iButtonWorker* worker);
|
||||
void ibutton_worker_mode_idle_tick(iButtonWorker* worker);
|
||||
@@ -65,7 +64,7 @@ void ibutton_worker_mode_idle_stop(iButtonWorker* worker) {
|
||||
|
||||
typedef struct {
|
||||
uint32_t last_dwt_value;
|
||||
StreamBufferHandle_t stream;
|
||||
FuriStreamBuffer* stream;
|
||||
} iButtonReadContext;
|
||||
|
||||
void ibutton_worker_comparator_callback(bool level, void* context) {
|
||||
@@ -75,7 +74,7 @@ void ibutton_worker_comparator_callback(bool level, void* context) {
|
||||
|
||||
LevelDuration data =
|
||||
level_duration_make(level, current_dwt_value - read_context->last_dwt_value);
|
||||
xStreamBufferSend(read_context->stream, &data, sizeof(LevelDuration), 0);
|
||||
furi_stream_buffer_send(read_context->stream, &data, sizeof(LevelDuration), 0);
|
||||
|
||||
read_context->last_dwt_value = current_dwt_value;
|
||||
}
|
||||
@@ -91,7 +90,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) {
|
||||
|
||||
iButtonReadContext read_context = {
|
||||
.last_dwt_value = DWT->CYCCNT,
|
||||
.stream = xStreamBufferCreate(sizeof(LevelDuration) * 512, 1),
|
||||
.stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 512, 1),
|
||||
};
|
||||
|
||||
furi_hal_rfid_comp_set_callback(ibutton_worker_comparator_callback, &read_context);
|
||||
@@ -100,7 +99,8 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) {
|
||||
uint32_t tick_start = furi_get_tick();
|
||||
while(true) {
|
||||
LevelDuration level;
|
||||
size_t ret = xStreamBufferReceive(read_context.stream, &level, sizeof(LevelDuration), 100);
|
||||
size_t ret =
|
||||
furi_stream_buffer_receive(read_context.stream, &level, sizeof(LevelDuration), 100);
|
||||
|
||||
if((furi_get_tick() - tick_start) > 100) {
|
||||
break;
|
||||
@@ -141,7 +141,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) {
|
||||
furi_hal_rfid_comp_set_callback(NULL, NULL);
|
||||
furi_hal_rfid_pins_reset();
|
||||
|
||||
vStreamBufferDelete(read_context.stream);
|
||||
furi_stream_buffer_free(read_context.stream);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -54,7 +55,7 @@ void _putchar(char character);
|
||||
* \param format A string that specifies the format of the output
|
||||
* \return The number of characters that are written into the array, not counting the terminating null character
|
||||
*/
|
||||
int printf_(const char* format, ...);
|
||||
int printf_(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2)));
|
||||
|
||||
/**
|
||||
* Tiny sprintf implementation
|
||||
@@ -63,7 +64,7 @@ int printf_(const char* format, ...);
|
||||
* \param format A string that specifies the format of the output
|
||||
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
|
||||
*/
|
||||
int sprintf_(char* buffer, const char* format, ...);
|
||||
int sprintf_(char* buffer, const char* format, ...) _ATTRIBUTE((__format__(__printf__, 2, 3)));
|
||||
|
||||
/**
|
||||
* Tiny snprintf/vsnprintf implementation
|
||||
@@ -75,7 +76,8 @@ int sprintf_(char* buffer, const char* format, ...);
|
||||
* null character. A value equal or larger than count indicates truncation. Only when the returned value
|
||||
* is non-negative and less than count, the string has been completely written.
|
||||
*/
|
||||
int snprintf_(char* buffer, size_t count, const char* format, ...);
|
||||
int snprintf_(char* buffer, size_t count, const char* format, ...)
|
||||
_ATTRIBUTE((__format__(__printf__, 3, 4)));
|
||||
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va);
|
||||
|
||||
/**
|
||||
@@ -94,7 +96,8 @@ int vprintf_(const char* format, va_list va);
|
||||
* \param format A string that specifies the format of the output
|
||||
* \return The number of characters that are sent to the output function, not counting the terminating null character
|
||||
*/
|
||||
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
|
||||
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
|
||||
_ATTRIBUTE((__format__(__printf__, 3, 4)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+12
-11
@@ -4,7 +4,7 @@
|
||||
|
||||
#define TAG "SubGhzBlockGeneric"
|
||||
|
||||
void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str) {
|
||||
void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) {
|
||||
const char* preset_name_temp;
|
||||
if(!strcmp(preset_name, "AM270")) {
|
||||
preset_name_temp = "FuriHalSubGhzPresetOok270Async";
|
||||
@@ -17,7 +17,7 @@ void subghz_block_generic_get_preset_name(const char* preset_name, string_t pres
|
||||
} else {
|
||||
preset_name_temp = "FuriHalSubGhzPresetCustom";
|
||||
}
|
||||
string_set(preset_str, preset_name_temp);
|
||||
furi_string_set(preset_str, preset_name_temp);
|
||||
}
|
||||
|
||||
bool subghz_block_generic_serialize(
|
||||
@@ -26,8 +26,8 @@ bool subghz_block_generic_serialize(
|
||||
SubGhzPresetDefinition* preset) {
|
||||
furi_assert(instance);
|
||||
bool res = false;
|
||||
string_t temp_str;
|
||||
string_init(temp_str);
|
||||
FuriString* temp_str;
|
||||
temp_str = furi_string_alloc();
|
||||
do {
|
||||
stream_clean(flipper_format_get_raw_stream(flipper_format));
|
||||
if(!flipper_format_write_header_cstr(
|
||||
@@ -41,12 +41,13 @@ bool subghz_block_generic_serialize(
|
||||
break;
|
||||
}
|
||||
|
||||
subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str);
|
||||
if(!flipper_format_write_string_cstr(flipper_format, "Preset", string_get_cstr(temp_str))) {
|
||||
subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str);
|
||||
if(!flipper_format_write_string_cstr(
|
||||
flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
|
||||
FURI_LOG_E(TAG, "Unable to add Preset");
|
||||
break;
|
||||
}
|
||||
if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
|
||||
if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
|
||||
if(!flipper_format_write_string_cstr(
|
||||
flipper_format, "Custom_preset_module", "CC1101")) {
|
||||
FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
|
||||
@@ -79,15 +80,15 @@ bool subghz_block_generic_serialize(
|
||||
}
|
||||
res = true;
|
||||
} while(false);
|
||||
string_clear(temp_str);
|
||||
furi_string_free(temp_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format) {
|
||||
furi_assert(instance);
|
||||
bool res = false;
|
||||
string_t temp_str;
|
||||
string_init(temp_str);
|
||||
FuriString* temp_str;
|
||||
temp_str = furi_string_alloc();
|
||||
uint32_t temp_data = 0;
|
||||
|
||||
do {
|
||||
@@ -113,7 +114,7 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma
|
||||
res = true;
|
||||
} while(0);
|
||||
|
||||
string_clear(temp_str);
|
||||
furi_string_free(temp_str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ struct SubGhzBlockGeneric {
|
||||
* @param preset_name name preset
|
||||
* @param preset_str Output name preset
|
||||
*/
|
||||
void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str);
|
||||
void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str);
|
||||
|
||||
/**
|
||||
* Serialize data SubGhzBlockGeneric.
|
||||
|
||||
@@ -11,7 +11,7 @@ void subghz_protocol_decoder_base_set_decoder_callback(
|
||||
|
||||
bool subghz_protocol_decoder_base_get_string(
|
||||
SubGhzProtocolDecoderBase* decoder_base,
|
||||
string_t output) {
|
||||
FuriString* output) {
|
||||
bool status = false;
|
||||
|
||||
if(decoder_base->protocol && decoder_base->protocol->decoder &&
|
||||
|
||||
@@ -11,8 +11,9 @@ typedef struct SubGhzProtocolDecoderBase SubGhzProtocolDecoderBase;
|
||||
typedef void (
|
||||
*SubGhzProtocolDecoderBaseRxCallback)(SubGhzProtocolDecoderBase* instance, void* context);
|
||||
|
||||
typedef void (
|
||||
*SubGhzProtocolDecoderBaseSerialize)(SubGhzProtocolDecoderBase* decoder_base, string_t output);
|
||||
typedef void (*SubGhzProtocolDecoderBaseSerialize)(
|
||||
SubGhzProtocolDecoderBase* decoder_base,
|
||||
FuriString* output);
|
||||
|
||||
struct SubGhzProtocolDecoderBase {
|
||||
// Decoder general section
|
||||
@@ -41,7 +42,7 @@ void subghz_protocol_decoder_base_set_decoder_callback(
|
||||
*/
|
||||
bool subghz_protocol_decoder_base_get_string(
|
||||
SubGhzProtocolDecoderBase* decoder_base,
|
||||
string_t output);
|
||||
FuriString* output);
|
||||
|
||||
/**
|
||||
* Serialize data SubGhzProtocolDecoderBase.
|
||||
|
||||
@@ -323,11 +323,11 @@ bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flip
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_bett_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderBETT* instance = context;
|
||||
uint32_t data = (uint32_t)(instance->generic.data & 0x3FFFF);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%05lX\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flip
|
||||
* @param context Pointer to a SubGhzProtocolDecoderBETT instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_bett_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -322,7 +322,7 @@ bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flip
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_came_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_came_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderCame* instance = context;
|
||||
|
||||
@@ -333,7 +333,7 @@ void subghz_protocol_decoder_came_get_string(void* context, string_t output) {
|
||||
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%08lX\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flip
|
||||
* @param context Pointer to a SubGhzProtocolDecoderCame instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_came_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_came_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -325,7 +325,7 @@ bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderCameAtomo* instance = context;
|
||||
subghz_protocol_came_atomo_remote_controller(
|
||||
@@ -333,12 +333,12 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t outpu
|
||||
uint32_t code_found_hi = instance->generic.data >> 32;
|
||||
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %db\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
"Sn:0x%08lX Btn:0x%01X\r\n"
|
||||
"Cnt:0x%03X\r\n",
|
||||
"Cnt:0x%03lX\r\n",
|
||||
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
|
||||
@@ -69,4 +69,4 @@ bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat
|
||||
* @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -446,18 +446,18 @@ bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderCameTwee* instance = context;
|
||||
subghz_protocol_came_twee_remote_controller(&instance->generic);
|
||||
uint32_t code_found_hi = instance->generic.data >> 32;
|
||||
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %db\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
"Btn:%lX\r\n"
|
||||
"Btn:%X\r\n"
|
||||
"DIP:" DIP_PATTERN "\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat*
|
||||
* @param context Pointer to a SubGhzProtocolDecoderCameTwee instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -451,7 +451,7 @@ bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderChamb_Code* instance = context;
|
||||
|
||||
@@ -462,7 +462,7 @@ void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t outpu
|
||||
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %db\r\n"
|
||||
"Key:0x%03lX\r\n"
|
||||
@@ -474,19 +474,19 @@ void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t outpu
|
||||
|
||||
switch(instance->generic.data_count_bit) {
|
||||
case 7:
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"DIP:" CHAMBERLAIN_7_CODE_DIP_PATTERN "\r\n",
|
||||
CHAMBERLAIN_7_CODE_DATA_TO_DIP(code_found_lo));
|
||||
break;
|
||||
case 8:
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"DIP:" CHAMBERLAIN_8_CODE_DIP_PATTERN "\r\n",
|
||||
CHAMBERLAIN_8_CODE_DATA_TO_DIP(code_found_lo));
|
||||
break;
|
||||
case 9:
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"DIP:" CHAMBERLAIN_9_CODE_DIP_PATTERN "\r\n",
|
||||
CHAMBERLAIN_9_CODE_DATA_TO_DIP(code_found_lo));
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat
|
||||
* @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -343,12 +343,12 @@ bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* fl
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_clemsa_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderClemsa* instance = context;
|
||||
subghz_protocol_clemsa_check_remote_controller(&instance->generic);
|
||||
//uint32_t data = (uint32_t)(instance->generic.data & 0xFFFFFF);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%05lX Btn %X\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* fl
|
||||
* @param context Pointer to a SubGhzProtocolDecoderClemsa instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_clemsa_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -337,15 +337,15 @@ bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_doitrand_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderDoitrand* instance = context;
|
||||
subghz_protocol_doitrand_check_remote_controller(&instance->generic);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%02lX%08lX\r\n"
|
||||
"Btn:%lX\r\n"
|
||||
"Btn:%X\r\n"
|
||||
"DIP:" DIP_PATTERN "\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat*
|
||||
* @param context Pointer to a SubGhzProtocolDecoderDoitrand instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_doitrand_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -207,7 +207,7 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderFaacSLH* instance = context;
|
||||
subghz_protocol_faac_slh_check_remote_controller(&instance->generic);
|
||||
@@ -216,13 +216,13 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output)
|
||||
uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
|
||||
uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%lX%08lX\r\n"
|
||||
"Fix:%08lX \r\n"
|
||||
"Hop:%08lX \r\n"
|
||||
"Sn:%07lX Btn:%lX\r\n",
|
||||
"Sn:%07lX Btn:%X\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)(instance->generic.data >> 32),
|
||||
|
||||
@@ -70,4 +70,4 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat*
|
||||
* @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -317,15 +317,15 @@ bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* f
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderGateTx* instance = context;
|
||||
subghz_protocol_gate_tx_check_remote_controller(&instance->generic);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%06lX\r\n"
|
||||
"Sn:%05lX Btn:%lX\r\n",
|
||||
"Sn:%05lX Btn:%X\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)(instance->generic.data & 0xFFFFFF),
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* f
|
||||
* @param context Pointer to a SubGhzProtocolDecoderGateTx instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -350,12 +350,12 @@ bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* fl
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderHoltek* instance = context;
|
||||
subghz_protocol_holtek_check_remote_controller(&instance->generic);
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
@@ -368,8 +368,8 @@ void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) {
|
||||
instance->generic.btn >> 4);
|
||||
|
||||
if((instance->generic.btn & 0xF) == 0xE) {
|
||||
string_cat_printf(output, "ON\r\n");
|
||||
furi_string_cat_printf(output, "ON\r\n");
|
||||
} else if(((instance->generic.btn & 0xF) == 0xB)) {
|
||||
string_cat_printf(output, "OFF\r\n");
|
||||
furi_string_cat_printf(output, "OFF\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* fl
|
||||
* @param context Pointer to a SubGhzProtocolDecoderHoltek instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_holtek_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -374,18 +374,18 @@ bool subghz_protocol_decoder_honeywell_wdb_deserialize(
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderHoneywell_WDB* instance = context;
|
||||
subghz_protocol_honeywell_wdb_check_remote_controller(instance);
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
"Sn:0x%05lX\r\n"
|
||||
"DT:%s Al:%s\r\n"
|
||||
"SK:%01lX R:%01lX LBat:%01lX\r\n",
|
||||
"SK:%01X R:%01X LBat:%01X\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF),
|
||||
|
||||
@@ -108,4 +108,4 @@ bool subghz_protocol_decoder_honeywell_wdb_deserialize(
|
||||
* @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -338,12 +338,12 @@ bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* f
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_hormann_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderHormann* instance = context;
|
||||
subghz_protocol_hormann_check_remote_controller(&instance->generic);
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s\r\n"
|
||||
"%dbit\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* f
|
||||
* @param context Pointer to a SubGhzProtocolDecoderHormann instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_hormann_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -205,7 +205,7 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_ido_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderIDo* instance = context;
|
||||
|
||||
@@ -215,13 +215,13 @@ void subghz_protocol_decoder_ido_get_string(void* context, string_t output) {
|
||||
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
|
||||
uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
"Fix:%06lX \r\n"
|
||||
"Hop:%06lX \r\n"
|
||||
"Sn:%05lX Btn:%lX\r\n",
|
||||
"Sn:%05lX Btn:%X\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)(instance->generic.data >> 32),
|
||||
|
||||
@@ -70,4 +70,4 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp
|
||||
* @param context Pointer to a SubGhzProtocolDecoderIDo instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_ido_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -434,13 +434,13 @@ bool subghz_protocol_decoder_intertechno_v3_deserialize(
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderIntertechno_V3* instance = context;
|
||||
|
||||
subghz_protocol_intertechno_v3_check_remote_controller(&instance->generic);
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%.11s %db\r\n"
|
||||
"Key:0x%08llX\r\n"
|
||||
@@ -453,17 +453,17 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t o
|
||||
if(instance->generic.data_count_bit ==
|
||||
subghz_protocol_intertechno_v3_const.min_count_bit_for_found) {
|
||||
if(instance->generic.cnt >> 5) {
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output, "Ch: All Btn:%s\r\n", (instance->generic.btn ? "On" : "Off"));
|
||||
} else {
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"Ch:" CH_PATTERN " Btn:%s\r\n",
|
||||
CNT_TO_CH(instance->generic.cnt),
|
||||
(instance->generic.btn ? "On" : "Off"));
|
||||
}
|
||||
} else if(instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) {
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"Ch:" CH_PATTERN " Dimm:%d%%\r\n",
|
||||
CNT_TO_CH(instance->generic.cnt),
|
||||
|
||||
@@ -108,4 +108,4 @@ bool subghz_protocol_decoder_intertechno_v3_deserialize(
|
||||
* @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "keeloq_common.h"
|
||||
|
||||
#include "../subghz_keystore.h"
|
||||
#include <m-string.h>
|
||||
#include <m-array.h>
|
||||
|
||||
#include "../blocks/const.h"
|
||||
@@ -131,7 +130,7 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc
|
||||
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
|
||||
res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name);
|
||||
res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
|
||||
if(res == 0) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
@@ -489,7 +488,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -499,7 +498,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -508,7 +507,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
fix, seed, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -517,7 +516,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -526,7 +525,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -534,7 +533,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -548,7 +547,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -558,7 +557,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -566,7 +565,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
man = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -575,7 +574,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
fix, seed, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -583,7 +582,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
man = subghz_protocol_keeloq_common_secure_learning(fix, seed, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -592,7 +591,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -600,7 +599,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = string_get_cstr(manufacture_code->name);
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -683,7 +682,7 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl
|
||||
return res;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderKeeloq* instance = context;
|
||||
subghz_protocol_keeloq_check_remote_controller(
|
||||
@@ -697,12 +696,12 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output) {
|
||||
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%08lX%08lX\r\n"
|
||||
"Fix:0x%08lX Cnt:%04X\r\n"
|
||||
"Hop:0x%08lX Btn:%01lX\r\n"
|
||||
"Fix:0x%08lX Cnt:%04lX\r\n"
|
||||
"Hop:0x%08lX Btn:%01X\r\n"
|
||||
"MF:%s\r\n"
|
||||
"Sn:0x%07lX \r\n",
|
||||
instance->generic.protocol_name,
|
||||
|
||||
@@ -124,4 +124,4 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl
|
||||
* @param context Pointer to a SubGhzProtocolDecoderKeeloq instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#include <m-string.h>
|
||||
#include <m-array.h>
|
||||
|
||||
#define bit(x, n) (((x) >> (n)) & 1)
|
||||
|
||||
@@ -256,7 +256,7 @@ bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipp
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_kia_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderKIA* instance = context;
|
||||
|
||||
@@ -264,11 +264,11 @@ void subghz_protocol_decoder_kia_get_string(void* context, string_t output) {
|
||||
uint32_t code_found_hi = instance->generic.data >> 32;
|
||||
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%08lX%08lX\r\n"
|
||||
"Sn:%07lX Btn:%lX Cnt:%04X\r\n",
|
||||
"Sn:%07lX Btn:%X Cnt:%04lX\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
code_found_hi,
|
||||
|
||||
@@ -70,4 +70,4 @@ bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipp
|
||||
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_kia_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -327,7 +327,7 @@ bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* fl
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_linear_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderLinear* instance = context;
|
||||
|
||||
@@ -338,7 +338,7 @@ void subghz_protocol_decoder_linear_get_string(void* context, string_t output) {
|
||||
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%08lX\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* fl
|
||||
* @param context Pointer to a SubGhzProtocolDecoderLinear instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_linear_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -375,8 +375,8 @@ static void subghz_protocol_magellen_check_remote_controller(SubGhzBlockGeneric*
|
||||
instance->btn = (data_rev >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
static void subghz_protocol_magellen_get_event_serialize(uint8_t event, string_t output) {
|
||||
string_cat_printf(
|
||||
static void subghz_protocol_magellen_get_event_serialize(uint8_t event, FuriString* output) {
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s%s%s%s%s%s%s%s",
|
||||
((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") :
|
||||
@@ -424,15 +424,15 @@ bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_magellen_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderMagellen* instance = context;
|
||||
subghz_protocol_magellen_check_remote_controller(&instance->generic);
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%08lX\r\n"
|
||||
"Sn:%03d%03d, Event:0x%02X\r\n"
|
||||
"Sn:%03ld%03ld, Event:0x%02X\r\n"
|
||||
"Stat:",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat*
|
||||
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_magellen_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -373,17 +373,17 @@ bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_marantec_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderMarantec* instance = context;
|
||||
subghz_protocol_marantec_remote_controller(&instance->generic);
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %db\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
"Sn:0x%07lX \r\n"
|
||||
"Btn:%lX\r\n",
|
||||
"Btn:%X\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)(instance->generic.data >> 32),
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat*
|
||||
* @param context Pointer to a SubGhzProtocolDecoderMarantec instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_marantec_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -408,17 +408,17 @@ bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_megacode_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderMegaCode* instance = context;
|
||||
subghz_protocol_megacode_check_remote_controller(&instance->generic);
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%06lX\r\n"
|
||||
"Sn:0x%04lX - %d\r\n"
|
||||
"Facility:%X Btn:%X\r\n",
|
||||
"Sn:0x%04lX - %ld\r\n"
|
||||
"Facility:%lX Btn:%X\r\n",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)instance->generic.data,
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat*
|
||||
* @param context Pointer to a SubGhzProtocolDecoderMegaCode instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_megacode_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -370,7 +370,7 @@ bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderNeroRadio* instance = context;
|
||||
|
||||
@@ -383,7 +383,7 @@ void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t outpu
|
||||
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat
|
||||
* @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -355,7 +355,7 @@ bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperForma
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderNeroSketch* instance = context;
|
||||
|
||||
@@ -368,7 +368,7 @@ void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t outp
|
||||
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%lX%08lX\r\n"
|
||||
|
||||
@@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperForma
|
||||
* @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output);
|
||||
void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output);
|
||||
|
||||
@@ -309,7 +309,7 @@ bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat*
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output) {
|
||||
void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderNiceFlo* instance = context;
|
||||
|
||||
@@ -318,7 +318,7 @@ void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output)
|
||||
instance->generic.data, instance->generic.data_count_bit);
|
||||
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
|
||||
|
||||
string_cat_printf(
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:0x%08lX\r\n"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user