83 lines
3.6 KiB
C
83 lines
3.6 KiB
C
#ifndef SD_FILE_BROWSER_H
|
||
#define SD_FILE_BROWSER_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/* Ограничения одинаковы для portable core, Modbus mailbox и GUI. */
|
||
#define SD_FILE_BROWSER_MAX_PATH 96U
|
||
#define SD_FILE_BROWSER_MAX_NAME 48U
|
||
#define SD_FILE_BROWSER_MAX_PAGE_ITEMS 3U
|
||
#define SD_FILE_BROWSER_MAX_CHUNK_BYTES 64U
|
||
|
||
typedef enum {
|
||
/* Успех означает полностью сформированную страницу, а не только open. */
|
||
SD_FILE_BROWSER_OK = 0,
|
||
/* BUSY оставляет retry политике приложения и ничего не пишет на носитель. */
|
||
SD_FILE_BROWSER_BUSY,
|
||
SD_FILE_BROWSER_NOT_READY,
|
||
SD_FILE_BROWSER_IO_ERROR,
|
||
SD_FILE_BROWSER_INVALID_PATH,
|
||
SD_FILE_BROWSER_INVALID_CURSOR,
|
||
SD_FILE_BROWSER_NAME_TOO_LONG,
|
||
SD_FILE_BROWSER_FILE_CHANGED,
|
||
SD_FILE_BROWSER_NOT_LOG_FILE
|
||
} SdFileBrowserStatus;
|
||
|
||
typedef struct {
|
||
/* Имя всегда завершается нулём и не содержит родительского пути. */
|
||
char name[SD_FILE_BROWSER_MAX_NAME + 1U];
|
||
uint32_t size;
|
||
uint16_t modified_date;
|
||
uint16_t modified_time;
|
||
uint8_t is_directory;
|
||
} SdFileBrowserEntry;
|
||
|
||
typedef struct {
|
||
/* Ответ имеет фиксированную RAM-ёмкость и никогда не выделяет heap. */
|
||
SdFileBrowserEntry items[SD_FILE_BROWSER_MAX_PAGE_ITEMS];
|
||
uint16_t next_offset;
|
||
uint8_t count;
|
||
uint8_t has_more;
|
||
} SdFileBrowserPage;
|
||
|
||
typedef struct {
|
||
/* Metadata повторяется в каждом chunk и защищает bridge от склейки разных версий файла. */
|
||
uint32_t total_size;
|
||
uint32_t offset;
|
||
uint16_t modified_date;
|
||
uint16_t modified_time;
|
||
uint8_t length;
|
||
uint8_t end_of_file;
|
||
uint8_t data[SD_FILE_BROWSER_MAX_CHUNK_BYTES];
|
||
} SdFileBrowserChunk;
|
||
|
||
typedef SdFileBrowserStatus (*SdFileBrowserListPageFn)(
|
||
void *context, const char *path, uint16_t offset, uint8_t limit,
|
||
SdFileBrowserPage *page);
|
||
|
||
typedef struct {
|
||
/* Context принадлежит платформе; portable core его не освобождает. */
|
||
void *context;
|
||
SdFileBrowserListPageFn list_page;
|
||
} SdFileBrowser;
|
||
|
||
/* Принимается только логический путь от корня карты: "/" или "/dir/file".
|
||
* Проверка не исправляет вход: неканонические строки отклоняются fail-closed. */
|
||
SdFileBrowserStatus SdFileBrowser_ValidatePath(const char *path);
|
||
|
||
/* Разрешает только legacy TEMPLOG.MD или суточный temperature_*.md внутри
|
||
* штатного корня niceOne/mounth; служебные JSON/прошивки сюда не попадают. */
|
||
SdFileBrowserStatus SdFileBrowser_ValidateLogFilePath(const char *path);
|
||
|
||
/* Разрешает только сырой образ .bin/.fw внутри каталога niceOne/firmware.
|
||
* Каталог отделён от журналов, чтобы прошивка и логи не смешивались. */
|
||
SdFileBrowserStatus SdFileBrowser_ValidateFirmwarePath(const char *path);
|
||
|
||
/* Вызов делегирует порту ровно одну ограниченную страницу каталога.
|
||
* Output предварительно очищается, поэтому ошибка не публикует старые имена. */
|
||
SdFileBrowserStatus SdFileBrowser_ListPage(
|
||
const SdFileBrowser *browser, const char *path, uint16_t offset,
|
||
uint8_t limit, SdFileBrowserPage *page);
|
||
|
||
#endif /* SD_FILE_BROWSER_H */
|