Added mcumgr/smp v2 commands for listing and deleting files
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user