Added mcumgr/smp v2 commands for listing and deleting files
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s

This commit is contained in:
2026-02-12 11:26:43 +01:00
parent 0785d9a755
commit 794d8e36c9
2 changed files with 176 additions and 1 deletions

View File

@@ -9,6 +9,14 @@ menuconfig FS_MGMT
Library for initializing and managing the file system.
if FS_MGMT
config FS_MGMT_MCUMGR_HANDLER
bool "Enable Custom MCUMGR FS Handlers"
default y
depends on MCUMGR_GRP_FS
help
Enables the custom MCUMGR group (ID 64) for listing (ls)
and removing (rm) files via SMP.
# Logging configuration for the File System Management module
module = FS_MGMT
module-str = fs_mgmt

View File

@@ -15,6 +15,167 @@ static struct fs_mount_t fs_storage_mnt = {
.mnt_point = "/lfs",
};
#ifdef CONFIG_FS_MGMT_MCUMGR_HANDLER
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/smp/smp.h>
#include <zephyr/fs/fs.h>
#include <zcbor_decode.h>
#include <zcbor_encode.h>
#include <mgmt/mcumgr/util/zcbor_bulk.h>
#define CUSTOM_GROUP_ID 64
#define CMD_LS 0
#define CMD_RM 1
static int custom_ls_handler(struct smp_streamer *ctxt)
{
struct fs_dir_t dirp;
struct fs_dirent entry;
int file_count = 0;
char path[64] = ""; // Startet leer
zcbor_state_t *zsd = ctxt->reader->zs;
zcbor_state_t *zse = ctxt->writer->zs;
/* --- DECODING --- */
struct zcbor_string res_path = {0};
bool path_found = false;
if (zcbor_map_start_decode(zsd))
{
while (zcbor_tstr_decode(zsd, &res_path))
{
if (res_path.len == 4 && memcmp(res_path.value, "path", 4) == 0)
{
struct zcbor_string path_val;
if (zcbor_tstr_decode(zsd, &path_val))
{
int len = MIN(path_val.len, sizeof(path) - 1);
memcpy(path, path_val.value, len);
path[len] = '\0';
path_found = true;
}
}
else
{
zcbor_any_skip(zsd, NULL);
}
}
zcbor_map_end_decode(zsd);
}
// Falls kein Pfad gesendet wurde, fange im Root an
if (!path_found || strlen(path) == 0)
{
strcpy(path, "/");
}
/* --- PROCESSING & ENCODING --- */
fs_dir_t_init(&dirp);
if (fs_opendir(&dirp, path) != 0)
return MGMT_ERR_ENOENT;
// Zählen...
while (fs_readdir(&dirp, &entry) == 0 && entry.name[0] != '\0')
{
file_count++;
}
fs_closedir(&dirp);
bool ok = zcbor_tstr_put_lit(zse, "files") && zcbor_list_start_encode(zse, file_count);
if (fs_opendir(&dirp, path) == 0)
{
while (fs_readdir(&dirp, &entry) == 0 && entry.name[0] != '\0')
{
const char *type_char = (entry.type == FS_DIR_ENTRY_DIR) ? "d" : "f";
ok = ok && zcbor_map_start_encode(zse, 2) &&
zcbor_tstr_put_lit(zse, "n") &&
zcbor_tstr_encode(zse, &(struct zcbor_string){.value = (const uint8_t *)entry.name, .len = strlen(entry.name)}) &&
zcbor_tstr_put_lit(zse, "t") &&
zcbor_tstr_encode(zse, &(struct zcbor_string){.value = (const uint8_t *)type_char, .len = 1}) &&
zcbor_map_end_encode(zse, 2);
}
fs_closedir(&dirp);
}
ok = ok && zcbor_list_end_encode(zse, file_count);
return ok ? 0 : MGMT_ERR_ENOMEM;
}
static int custom_rm_handler(struct smp_streamer *ctxt)
{
char path[64] = {0};
zcbor_state_t *zsd = ctxt->reader->zs;
zcbor_state_t *zse = ctxt->writer->zs;
bool path_found = false;
struct zcbor_string key;
/* --- DECODING --- */
if (!zcbor_map_start_decode(zsd))
{
return MGMT_ERR_EINVAL;
}
while (zcbor_tstr_decode(zsd, &key))
{
if (key.len == 4 && memcmp(key.value, "path", 4) == 0)
{
struct zcbor_string val;
if (zcbor_tstr_decode(zsd, &val))
{
size_t len = MIN(val.len, sizeof(path) - 1);
memcpy(path, val.value, len);
path[len] = '\0';
path_found = true;
}
}
else
{
zcbor_any_skip(zsd, NULL);
}
}
zcbor_map_end_decode(zsd);
if (!path_found)
{
return MGMT_ERR_EINVAL;
}
/* --- PROCESSING --- */
int rc = fs_unlink(path);
/* --- ENCODING RESPONSE --- */
// Wir senden den Return-Code zurück (0 = Erfolg)
bool ok = zcbor_tstr_put_lit(zse, "rc") && zcbor_int32_put(zse, rc);
if (rc != 0)
{
LOG_WRN("Failed to remove %s: %d", path, rc);
// Optional: Spezifische mgmt_err Mapping
return (rc == -ENOENT) ? MGMT_ERR_ENOENT : MGMT_ERR_EUNKNOWN;
}
return ok ? 0 : MGMT_ERR_ENOMEM;
}
static const struct mgmt_handler custom_handlers[] = {
[CMD_LS] = {
.mh_read = custom_ls_handler,
.mh_write = NULL},
[CMD_RM] = {
.mh_read = NULL,
.mh_write = custom_rm_handler // Nutzung von WRITE für Löschvorgänge
},
};
static struct mgmt_group custom_group = {
.mg_handlers = custom_handlers,
.mg_handlers_count = ARRAY_SIZE(custom_handlers),
.mg_group_id = CUSTOM_GROUP_ID,
};
#endif /* CONFIG_FS_MGMT_MCUMGR_HANDLER */
int fs_mgmt_init(void)
{
int rc;
@@ -74,5 +235,11 @@ int fs_mgmt_init(void)
LOG_WRN("Filesystem statvfs failed (err %d)", rc);
}
}
#ifdef CONFIG_FS_MGMT_MCUMGR_HANDLER
mgmt_register_group(&custom_group);
LOG_DBG("Custom MCUMGR group registered with ID %d", CUSTOM_GROUP_ID);
#endif /* CONFIG_FS_MGMT_MCUMGR_HANDLER */
return 0;
}
}