47typedef enum : uint8_t {
92 (uint32_t)(sum >> 1U) + (uint32_t)name83[i]);
115 const uint32_t pos = base + i;
121 }
else if (pos == nlen) {
152 const uint32_t val = (uint32_t)ent[off] | ((uint32_t)ent[off + 1U] << 8U);
153 const uint32_t pos = base + i;
166 s->
units[pos] = (uint16_t)val;
174 if ((s->
have == 0U) || (s->
units[0] == 0U)) {
195typedef enum : uint8_t {
235 const uint16_t* needle,
241 uint32_t* out_entry_off,
261 uint32_t lnunits = 0U;
263 if ((lunits !=
nullptr) && (
priv_utf16_ieq(needle, nneedle, lunits, lnunits) != 0U)) {
279 uint32_t* out_entry_off,
282 const char* want_leaf = want;
283 if (want_leaf[0] ==
'/') {
287 uint32_t nneedle = 0U;
333 uint32_t cur = start;
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_protocol_error
Protocol-level error (e.g.
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
ra8_err_t priv_fat_get(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t *out_value)
Fetch the FAT entry for cluster, returning the next-cluster value.
ra8_err_t priv_fat_set(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t value)
Write value into the FAT entry for cluster across every FAT copy.
uint32_t priv_dir_eps(const ra8_fs_mount_t *m)
Directory entries per sector on one mounted volume.
uint8_t priv_is_eoc(const ra8_fs_mount_t *m, uint32_t value)
Test whether value is an end-of-chain marker for this FAT type.
ra8_err_t priv_read_sector(const ra8_fs_mount_t *m, uint64_t lba, uint8_t *buf)
Read a single sector into the module scratch buffer.
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
void priv_wr16(uint8_t *p, uint16_t v)
Encode a little-endian uint16_t into a byte buffer.
void priv_free_count_gave(const ra8_fs_mount_t *m, uint32_t n)
Account n clusters as returned to the volume's free space.
void priv_alloc_hint_lower(const ra8_fs_mount_t *m, uint32_t cluster)
Pull the next-free hint back to cluster if it is further on.
uint8_t * priv_sec_walk(void)
The WALK-role sector buffer (directory scans and entry RMW).
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
uint8_t priv_sfn_checksum(const uint8_t *name83)
Compute the 8.3 short-name checksum carried in each LFN directory entry.
static const uint8_t s_lfn_char_off[k_lfn_chars_per_ent]
Byte offset of each of an LFN entry's thirteen name characters.
static ra8_fs_lfn_scan_t internal_dir_find_long_sector(const ra8_fs_mount_t *m, const uint16_t *needle, uint32_t nneedle, const uint8_t *buf, uint64_t cur_lba, lfn_state_t *lfn, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes])
Scan one directory sector for a long-name match, updating the chain.
ra8_fs_lfn_scan_t
Outcome of scanning one directory sector for a long-name match.
@ k_lfn_scan_eod
End-of-directory marker hit; stop the walk.
@ k_lfn_scan_continue
No match in this sector; advance to the next.
@ k_lfn_scan_found
Long name matched; out parameters populated.
ra8_fs_lfn_char_off_t
Byte offsets of the 13 UTF-16 name characters in a 32-byte LFN entry.
@ k_lfn_char_off_12
LDIR_Name3 char 1.
@ k_lfn_char_off_8
LDIR_Name2 char 3.
@ k_lfn_char_off_0
LDIR_Name1 char 0.
@ k_lfn_char_off_9
LDIR_Name2 char 4.
@ k_lfn_char_off_6
LDIR_Name2 char 1.
@ k_lfn_char_off_3
LDIR_Name1 char 3.
@ k_lfn_char_off_4
LDIR_Name1 char 4.
@ k_lfn_char_off_7
LDIR_Name2 char 2.
@ k_lfn_char_off_5
LDIR_Name2 char 0.
@ k_lfn_char_off_11
LDIR_Name3 char 0.
@ k_lfn_char_off_2
LDIR_Name1 char 2.
@ k_lfn_char_off_1
LDIR_Name1 char 1.
@ k_lfn_char_off_10
LDIR_Name2 char 5.
void priv_lfn_fill_slot(uint8_t *ent, const uint16_t *name, uint32_t nlen, uint32_t order, uint8_t is_last, uint8_t csum)
Fill one 32-byte slot with the order -th group of a long name.
ra8_err_t priv_free_chain(const ra8_fs_mount_t *m, uint32_t start)
Free an entire cluster chain starting at start.
void priv_lfn_add(lfn_state_t *s, const uint8_t *ent)
Fold one LFN directory entry's 13 UTF-16LE code units into the state.
const uint16_t * priv_lfn_units_for(const lfn_state_t *s, const uint8_t *name83, uint32_t *out_units)
Code units of the chain that precedes name83, or NULL if none.
ra8_err_t priv_dir_find_long(const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *want, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes])
Find a directory entry by its VFAT long name (case-insensitive).
void priv_lfn_reset(lfn_state_t *s)
Reset the LFN reassembly state so a fresh chain can start.
void priv_dir_walk_init_loc(const ra8_fs_mount_t *m, const dir_loc_t *loc, dir_walk_t *w)
Initialise a directory walker for an arbitrary directory location.
ra8_err_t priv_dir_walk_next_sector(const ra8_fs_mount_t *m, dir_walk_t *w, uint8_t *out_eod)
Advance the walker to the next sector.
@ k_dir_off_attr
MS FAT spec sec 6 "DIR_Attr".
@ k_dir_name_field_len
8 + 3 raw chars (no dot).
@ k_dir_off_name
MS FAT spec sec 6 "DIR_Name" (11 bytes).
@ k_dir_marker_free_used
Slot was used, deleted.
@ k_dir_marker_free_perm
End-of-directory.
@ k_cluster_free
Cluster free.
@ k_cluster_first_data
Cluster numbers start at 2.
@ k_lfn_unicode_pad
Slot padding past the name terminator.
@ k_sfn_csum_high_bit
Rotate-in bit when the running sum is odd.
@ k_lfn_off_type
LDIR_Type – zero for a name component.
@ k_lfn_seq_order_mask
Order = seq & 0x1F (1..20).
@ k_lfn_off_checksum
Checksum of the matching 8.3 name.
@ k_lfn_write_max
Longest name we WRITE (k_lfn_max_entries).
@ k_lfn_off_seq
Sequence/order byte (LDIR_Ord).
@ k_lfn_seq_last
Set on the last logical group.
@ k_lfn_max_entries
Cap so 19*13 = 247 chars fits the buffer.
@ k_lfn_chars_per_ent
UTF-16 chars carried per LFN entry.
@ k_lfn_off_clus_lo
LDIR_FstClusLO – must be written as 0.
@ k_ra8_fs_attr_lfn
Long-file-name marker (we skip).
@ k_ra8_fs_dir_entry_bytes
MS FAT spec sec 6 "Directory Entry".
uint8_t priv_utf16_ieq(const uint16_t *a, uint32_t an, const uint16_t *b, uint32_t bn)
Compare two UTF-16 names for case-insensitive equality.
ra8_err_t priv_utf8_to_utf16(const char *in, uint16_t *out, uint32_t cap, uint32_t *out_units)
Convert a NUL-terminated UTF-8 name into UTF-16LE code units.
Identifies the directory a lookup/scan should operate in.
Internal cursor used by the directory iterator.
uint64_t cur_lba
Currently loaded LBA.
In-progress reassembly of one LFN chain across the directory scan.
uint8_t checksum
8.3 checksum the chain claims.
uint8_t have
1 once any group has been accumulated.
uint16_t units[k_lfn_write_max]
Reassembled UTF-16LE units; 0 ends it.
Cached parse of one mounted FAT volume.
uint32_t count_of_clusters
Per MS spec: data_sectors / SPC.