mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-17 00:28:11 -07:00
Merge branch 'DigitalSequence_PulseReader' of https://github.com/g3gg0/flipperzero-firmware into DigitalSequence_PulseReader
This commit is contained in:
@@ -857,7 +857,7 @@ ReturnCode rfalIsoDepATTRIB(
|
||||
* \brief Deselects PICC
|
||||
*
|
||||
* This function sends a deselect command to PICC and waits for it`s
|
||||
* responce in a blocking way
|
||||
* response in a blocking way
|
||||
*
|
||||
* \return ERR_NONE : Deselect successfully sent and acknowledged by PICC
|
||||
* \return ERR_TIMEOUT: No response rcvd from PICC
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
#define RFAL_T4T_ISO7816_P2_SELECT_RETURN_FCI_TEMPLATE \
|
||||
0x00U /*!< b4b3 P2 value for Return FCI template */
|
||||
#define RFAL_T4T_ISO7816_P2_SELECT_NO_RESPONSE_DATA \
|
||||
0x0CU /*!< b4b3 P2 value for No responce data */
|
||||
0x0CU /*!< b4b3 P2 value for No response data */
|
||||
|
||||
#define RFAL_T4T_ISO7816_STATUS_COMPLETE \
|
||||
0x9000U /*!< Command completed \ Normal processing - No further qualification*/
|
||||
|
||||
+2
-2
@@ -3975,7 +3975,7 @@ FRESULT f_getcwd (
|
||||
#endif
|
||||
if (i == len) { /* Root-directory */
|
||||
*tp++ = '/';
|
||||
} else { /* Sub-directroy */
|
||||
} else { /* Sub-directory */
|
||||
do /* Add stacked path str */
|
||||
*tp++ = buff[i++];
|
||||
while (i < len);
|
||||
@@ -4673,7 +4673,7 @@ FRESULT f_mkdir (
|
||||
}
|
||||
}
|
||||
if (res == FR_OK) {
|
||||
res = dir_register(&dj); /* Register the object to the directoy */
|
||||
res = dir_register(&dj); /* Register the object to the directory */
|
||||
}
|
||||
if (res == FR_OK) {
|
||||
#if _FS_EXFAT
|
||||
|
||||
@@ -10,7 +10,7 @@ extern "C" {
|
||||
#define INFRARED_COMMON_CARRIER_FREQUENCY ((uint32_t)38000)
|
||||
#define INFRARED_COMMON_DUTY_CYCLE ((float)0.33)
|
||||
|
||||
/* if we want to see splitted raw signals during brutforce,
|
||||
/* if we want to see split raw signals during bruteforce,
|
||||
* we have to have RX raw timing delay less than TX */
|
||||
#define INFRARED_RAW_RX_TIMING_DELAY_US 150000
|
||||
#define INFRARED_RAW_TX_TIMING_DELAY_US 180000
|
||||
|
||||
@@ -88,7 +88,7 @@ static bool protocol_pyramid_can_be_decoded(uint8_t* data) {
|
||||
}
|
||||
uint8_t fmt_len = 105 - j;
|
||||
|
||||
// Only suppport 26bit format for now
|
||||
// Only support 26bit format for now
|
||||
if(fmt_len != 26) return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -856,7 +856,7 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice*
|
||||
bool old_format = false;
|
||||
// Read Mifare Classic format version
|
||||
if(!flipper_format_read_uint32(file, "Data format version", &data_format_version, 1)) {
|
||||
// Load unread sectors with zero keys access for backward compatability
|
||||
// Load unread sectors with zero keys access for backward compatibility
|
||||
if(!flipper_format_rewind(file)) break;
|
||||
old_format = true;
|
||||
} else {
|
||||
@@ -1125,7 +1125,7 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia
|
||||
}
|
||||
|
||||
do {
|
||||
// Check existance of shadow file
|
||||
// Check existence of shadow file
|
||||
nfc_device_get_shadow_path(path, temp_str);
|
||||
dev->shadow_file_exist =
|
||||
storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) == FSE_OK;
|
||||
|
||||
@@ -106,7 +106,7 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) {
|
||||
// Point to block 0 of sector 0, value 0
|
||||
temp_ptr = &data->block[0 * 4].value[0];
|
||||
// Read first 7 bytes of block 0 of sector 0 from last to first and convert them to uint64_t
|
||||
// 80 5C 23 8A 16 31 04 becomes 04 31 16 8A 23 5C 80, and equals to 36130104729284868 decimal
|
||||
// 04 31 16 8A 23 5C 80 becomes 80 5C 23 8A 16 31 04, and equals to 36130104729284868 decimal
|
||||
uint8_t card_number_arr[7];
|
||||
for(size_t i = 0; i < 7; i++) {
|
||||
card_number_arr[i] = temp_ptr[6 - i];
|
||||
|
||||
@@ -79,7 +79,7 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) {
|
||||
// Point to block 0 of sector 0, value 0
|
||||
temp_ptr = &data->block[0 * 4].value[0];
|
||||
// Read first 7 bytes of block 0 of sector 0 from last to first and convert them to uint64_t
|
||||
// 80 5C 23 8A 16 31 04 becomes 04 31 16 8A 23 5C 80, and equals to 36130104729284868 decimal
|
||||
// 04 31 16 8A 23 5C 80 becomes 80 5C 23 8A 16 31 04, and equals to 36130104729284868 decimal
|
||||
uint8_t card_number_arr[7];
|
||||
for(size_t i = 0; i < 7; i++) {
|
||||
card_number_arr[i] = temp_ptr[6 - i];
|
||||
|
||||
@@ -107,7 +107,7 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) {
|
||||
// Point to block 0 of sector 0, value 0
|
||||
temp_ptr = &data->block[0 * 4].value[0];
|
||||
// Read first 7 bytes of block 0 of sector 0 from last to first and convert them to uint64_t
|
||||
// 80 5C 23 8A 16 31 04 becomes 04 31 16 8A 23 5C 80, and equals to 36130104729284868 decimal
|
||||
// 04 31 16 8A 23 5C 80 becomes 80 5C 23 8A 16 31 04, and equals to 36130104729284868 decimal
|
||||
uint8_t card_number_arr[7];
|
||||
for(size_t i = 0; i < 7; i++) {
|
||||
card_number_arr[i] = temp_ptr[6 - i];
|
||||
|
||||
@@ -181,7 +181,7 @@ static bool protocol_cyfral_decoder_feed(ProtocolCyfral* proto, bool level, uint
|
||||
cyfral->index++;
|
||||
}
|
||||
|
||||
// succefully read 8 nibbles
|
||||
// successfully read 8 nibbles
|
||||
if(cyfral->index == 8) {
|
||||
cyfral->state = CYFRAL_READ_STOP_NIBBLE;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void subghz_environment_free(SubGhzEnvironment* instance);
|
||||
* Downloading the manufacture key file.
|
||||
* @param instance Pointer to a SubGhzEnvironment instance
|
||||
* @param filename Full path to the file
|
||||
* @return true On succes
|
||||
* @return true On success
|
||||
*/
|
||||
bool subghz_environment_load_keystore(SubGhzEnvironment* instance, const char* filename);
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <core/check.h>
|
||||
#include <core/common_defines.h>
|
||||
|
||||
#define STREAM_BUFFER_SIZE (32U)
|
||||
|
||||
void stream_free(Stream* stream) {
|
||||
furi_assert(stream);
|
||||
stream->vtable->free(stream);
|
||||
@@ -24,6 +26,82 @@ bool stream_seek(Stream* stream, int32_t offset, StreamOffset offset_type) {
|
||||
return stream->vtable->seek(stream, offset, offset_type);
|
||||
}
|
||||
|
||||
static bool stream_seek_to_char_forward(Stream* stream, char c) {
|
||||
// Search is starting from seconds character
|
||||
if(!stream_seek(stream, 1, StreamOffsetFromCurrent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search character in a stream
|
||||
bool result = false;
|
||||
while(!result) {
|
||||
uint8_t buffer[STREAM_BUFFER_SIZE] = {0};
|
||||
size_t ret = stream_read(stream, buffer, STREAM_BUFFER_SIZE);
|
||||
for(size_t i = 0; i < ret; i++) {
|
||||
if(buffer[i] == c) {
|
||||
stream_seek(stream, (int32_t)i - ret, StreamOffsetFromCurrent);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret != STREAM_BUFFER_SIZE) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool stream_seek_to_char_backward(Stream* stream, char c) {
|
||||
size_t anchor = stream_tell(stream);
|
||||
|
||||
// Special case, no previous characters
|
||||
if(anchor == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
while(!result) {
|
||||
// Seek back
|
||||
uint8_t buffer[STREAM_BUFFER_SIZE] = {0};
|
||||
size_t to_read = STREAM_BUFFER_SIZE;
|
||||
if(to_read > anchor) {
|
||||
to_read = anchor;
|
||||
}
|
||||
|
||||
anchor -= to_read;
|
||||
furi_check(stream_seek(stream, anchor, StreamOffsetFromStart));
|
||||
|
||||
size_t ret = stream_read(stream, buffer, to_read);
|
||||
for(size_t i = 0; i < ret; i++) {
|
||||
size_t cursor = ret - i - 1;
|
||||
if(buffer[cursor] == c) {
|
||||
result = true;
|
||||
furi_check(stream_seek(stream, anchor + cursor, StreamOffsetFromStart));
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if(ret != STREAM_BUFFER_SIZE) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool stream_seek_to_char(Stream* stream, char c, StreamDirection direction) {
|
||||
const size_t old_position = stream_tell(stream);
|
||||
|
||||
bool result = false;
|
||||
if(direction == StreamDirectionForward) {
|
||||
result = stream_seek_to_char_forward(stream, c);
|
||||
} else if(direction == StreamDirectionBackward) {
|
||||
result = stream_seek_to_char_backward(stream, c);
|
||||
}
|
||||
|
||||
// Rollback
|
||||
if(!result) {
|
||||
stream_seek(stream, old_position, StreamOffsetFromStart);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t stream_tell(Stream* stream) {
|
||||
furi_assert(stream);
|
||||
return stream->vtable->tell(stream);
|
||||
@@ -69,11 +147,10 @@ static bool stream_write_struct(Stream* stream, const void* context) {
|
||||
|
||||
bool stream_read_line(Stream* stream, FuriString* str_result) {
|
||||
furi_string_reset(str_result);
|
||||
const uint8_t buffer_size = 32;
|
||||
uint8_t buffer[buffer_size];
|
||||
uint8_t buffer[STREAM_BUFFER_SIZE];
|
||||
|
||||
do {
|
||||
uint16_t bytes_were_read = stream_read(stream, buffer, buffer_size);
|
||||
uint16_t bytes_were_read = stream_read(stream, buffer, STREAM_BUFFER_SIZE);
|
||||
if(bytes_were_read == 0) break;
|
||||
|
||||
bool result = false;
|
||||
|
||||
+27
-12
@@ -16,6 +16,11 @@ typedef enum {
|
||||
StreamOffsetFromEnd,
|
||||
} StreamOffset;
|
||||
|
||||
typedef enum {
|
||||
StreamDirectionForward,
|
||||
StreamDirectionBackward,
|
||||
} StreamDirection;
|
||||
|
||||
typedef bool (*StreamWriteCB)(Stream* stream, const void* context);
|
||||
|
||||
/**
|
||||
@@ -31,15 +36,15 @@ void stream_free(Stream* stream);
|
||||
void stream_clean(Stream* stream);
|
||||
|
||||
/**
|
||||
* Indicates that the rw pointer is at the end of the stream
|
||||
* Indicates that the RW pointer is at the end of the stream
|
||||
* @param stream Stream instance
|
||||
* @return true if rw pointer is at the end of the stream
|
||||
* @return false if rw pointer is not at the end of the stream
|
||||
* @return true if RW pointer is at the end of the stream
|
||||
* @return false if RW pointer is not at the end of the stream
|
||||
*/
|
||||
bool stream_eof(Stream* stream);
|
||||
|
||||
/**
|
||||
* Moves the rw pointer.
|
||||
* Moves the RW pointer.
|
||||
* @param stream Stream instance
|
||||
* @param offset how much to move the pointer
|
||||
* @param offset_type starting from what
|
||||
@@ -48,10 +53,20 @@ bool stream_eof(Stream* stream);
|
||||
*/
|
||||
bool stream_seek(Stream* stream, int32_t offset, StreamOffset offset_type);
|
||||
|
||||
/** Seek to next occurrence of the character
|
||||
*
|
||||
* @param stream Pointer to the stream instance
|
||||
* @param[in] c The Character
|
||||
* @param[in] direction The Direction
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool stream_seek_to_char(Stream* stream, char c, StreamDirection direction);
|
||||
|
||||
/**
|
||||
* Gets the value of the rw pointer
|
||||
* Gets the value of the RW pointer
|
||||
* @param stream Stream instance
|
||||
* @return size_t value of the rw pointer
|
||||
* @return size_t value of the RW pointer
|
||||
*/
|
||||
size_t stream_tell(Stream* stream);
|
||||
|
||||
@@ -101,13 +116,13 @@ bool stream_delete_and_insert(
|
||||
* Read line from a stream (supports LF and CRLF line endings)
|
||||
* @param stream
|
||||
* @param str_result
|
||||
* @return true if line lenght is not zero
|
||||
* @return true if line length is not zero
|
||||
* @return false otherwise
|
||||
*/
|
||||
bool stream_read_line(Stream* stream, FuriString* str_result);
|
||||
|
||||
/**
|
||||
* Moves the rw pointer to the start
|
||||
* Moves the RW pointer to the start
|
||||
* @param stream Stream instance
|
||||
*/
|
||||
bool stream_rewind(Stream* stream);
|
||||
@@ -157,7 +172,7 @@ size_t stream_write_vaformat(Stream* stream, const char* format, va_list args);
|
||||
|
||||
/**
|
||||
* Insert N chars to the stream, starting at the current pointer.
|
||||
* Data will be inserted, not overwritteт, so the stream will be increased in size.
|
||||
* Data will be inserted, not overwritten, so the stream will be increased in size.
|
||||
* @param stream Stream instance
|
||||
* @param data data to be inserted
|
||||
* @param size size of data to be inserted
|
||||
@@ -273,7 +288,7 @@ bool stream_delete_and_insert_vaformat(
|
||||
|
||||
/**
|
||||
* Remove N chars from the stream, starting at the current pointer.
|
||||
* The size may be larger than stream size, the stream will be cleared from current rw pointer to the end.
|
||||
* The size may be larger than stream size, the stream will be cleared from current RW pointer to the end.
|
||||
* @param stream Stream instance
|
||||
* @param size how many chars need to be deleted
|
||||
* @return true if the operation was successful
|
||||
@@ -282,7 +297,7 @@ bool stream_delete_and_insert_vaformat(
|
||||
bool stream_delete(Stream* stream, size_t size);
|
||||
|
||||
/**
|
||||
* Copy data from one stream to another. Data will be copied from current rw pointer and to current rw pointer.
|
||||
* Copy data from one stream to another. Data will be copied from current RW pointer and to current RW pointer.
|
||||
* @param stream_from
|
||||
* @param stream_to
|
||||
* @param size
|
||||
@@ -328,7 +343,7 @@ size_t stream_load_from_file(Stream* stream, Storage* storage, const char* path)
|
||||
size_t stream_save_to_file(Stream* stream, Storage* storage, const char* path, FS_OpenMode mode);
|
||||
|
||||
/**
|
||||
* Dump stream inner data (size, RW positiot, content)
|
||||
* Dump stream inner data (size, RW position, content)
|
||||
* @param stream Stream instance
|
||||
*/
|
||||
void stream_dump_data(Stream* stream);
|
||||
|
||||
@@ -60,6 +60,12 @@ ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* res
|
||||
|
||||
char type_code = furi_string_get_char(resource_manifest->linebuf, 0);
|
||||
switch(type_code) {
|
||||
case 'V':
|
||||
resource_manifest->entry.type = ResourceManifestEntryTypeVersion;
|
||||
break;
|
||||
case 'T':
|
||||
resource_manifest->entry.type = ResourceManifestEntryTypeTimestamp;
|
||||
break;
|
||||
case 'F':
|
||||
resource_manifest->entry.type = ResourceManifestEntryTypeFile;
|
||||
break;
|
||||
@@ -98,9 +104,9 @@ ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* res
|
||||
furi_string_right(resource_manifest->linebuf, offs + 1);
|
||||
|
||||
furi_string_set(resource_manifest->entry.name, resource_manifest->linebuf);
|
||||
} else if(resource_manifest->entry.type == ResourceManifestEntryTypeDirectory) { //-V547
|
||||
/* Parse directory entry
|
||||
D:<name> */
|
||||
} else { //-V547
|
||||
/* Everything else is plain key value. Parse version, timestamp or directory entry
|
||||
<Type>:<Value> */
|
||||
|
||||
/* Remove entry type code */
|
||||
furi_string_right(resource_manifest->linebuf, 2);
|
||||
@@ -113,3 +119,45 @@ ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* res
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ResourceManifestEntry*
|
||||
resource_manifest_reader_previous(ResourceManifestReader* resource_manifest) {
|
||||
furi_assert(resource_manifest);
|
||||
|
||||
// Snapshot position for rollback
|
||||
const size_t previous_position = stream_tell(resource_manifest->stream);
|
||||
|
||||
// We need to jump 2 lines back
|
||||
size_t jumps = 2;
|
||||
// Special case: end of the file.
|
||||
const bool was_eof = stream_eof(resource_manifest->stream);
|
||||
if(was_eof) {
|
||||
jumps = 1;
|
||||
}
|
||||
while(jumps) {
|
||||
if(!stream_seek_to_char(resource_manifest->stream, '\n', StreamDirectionBackward)) {
|
||||
break;
|
||||
}
|
||||
if(stream_tell(resource_manifest->stream) < (previous_position - 1)) {
|
||||
jumps--;
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: first line. Force seek to zero
|
||||
if(jumps == 1) {
|
||||
jumps = 0;
|
||||
stream_seek(resource_manifest->stream, 0, StreamOffsetFromStart);
|
||||
}
|
||||
|
||||
if(jumps == 0) {
|
||||
ResourceManifestEntry* entry = resource_manifest_reader_next(resource_manifest);
|
||||
// Special case: was end of the file, prevent loop
|
||||
if(was_eof) {
|
||||
stream_seek(resource_manifest->stream, -1, StreamOffsetFromCurrent);
|
||||
}
|
||||
return entry;
|
||||
} else {
|
||||
stream_seek(resource_manifest->stream, previous_position, StreamOffsetFromStart);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ extern "C" {
|
||||
|
||||
typedef enum {
|
||||
ResourceManifestEntryTypeUnknown = 0,
|
||||
ResourceManifestEntryTypeVersion,
|
||||
ResourceManifestEntryTypeTimestamp,
|
||||
ResourceManifestEntryTypeDirectory,
|
||||
ResourceManifestEntryTypeFile,
|
||||
} ResourceManifestEntryType;
|
||||
@@ -52,6 +54,18 @@ bool resource_manifest_reader_open(ResourceManifestReader* resource_manifest, co
|
||||
*/
|
||||
ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* resource_manifest);
|
||||
|
||||
/** Read previous file/dir entry from manifest
|
||||
*
|
||||
* You must be at the end of the manifest to use this function.
|
||||
* Intended to be used after reaching end with resource_manifest_reader_next
|
||||
*
|
||||
* @param resource_manifest Pointer to the ResourceManifestReader instance
|
||||
*
|
||||
* @return entry or NULL if end of file
|
||||
*/
|
||||
ResourceManifestEntry*
|
||||
resource_manifest_reader_previous(ResourceManifestReader* resource_manifest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
Reference in New Issue
Block a user