zwischenstand
This commit is contained in:
@@ -29,7 +29,9 @@ static struct fs_mount_t fs_storage_mnt = {
|
||||
static int open_count = 0;
|
||||
static struct k_mutex flash_pm_lock;
|
||||
|
||||
#define ACK_WATERMARK (CONFIG_BUZZ_PROTO_SLAB_COUNT / 4)
|
||||
// #define ACK_WATERMARK (CONFIG_BUZZ_PROTO_SLAB_COUNT / 4)
|
||||
#define INITIAL_CREDITS CONFIG_BUZZ_PROTO_SLAB_COUNT
|
||||
#define ACK_WATERMARK (MAX(2, MIN(8, CONFIG_BUZZ_PROTO_SLAB_COUNT / 4)))
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
@@ -40,7 +42,8 @@ typedef struct __attribute__((packed))
|
||||
|
||||
K_MSGQ_DEFINE(fs_write_msgq, sizeof(struct fs_write_msg), CONFIG_BUZZ_PROTO_SLAB_COUNT, 4);
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
FS_STATE_IDLE,
|
||||
FS_STATE_RECEIVING_FILE,
|
||||
FS_STATE_RECEIVING_TAGS,
|
||||
@@ -509,7 +512,8 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
if (rc == -EAGAIN)
|
||||
{
|
||||
LOG_WRN("Write timeout! Aborting transfer.");
|
||||
if (write_ctx.state == FS_STATE_RECEIVING_FILE) {
|
||||
if (write_ctx.state == FS_STATE_RECEIVING_FILE)
|
||||
{
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
fs_mgmt_pm_unlink(write_ctx.filename);
|
||||
}
|
||||
@@ -522,49 +526,56 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
case FS_STATE_IDLE:
|
||||
if (msg.op == FS_WRITE_OP_FILE_START)
|
||||
{
|
||||
if (msg.data_len >= sizeof(write_ctx.filename)) {
|
||||
if (msg.data_len >= sizeof(write_ctx.filename))
|
||||
{
|
||||
LOG_ERR("Filename too long");
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, ENAMETOOLONG, msg.slab_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
memcpy(write_ctx.filename, msg.slab_ptr + msg.data_offset, msg.data_len);
|
||||
write_ctx.filename[msg.data_len] = '\0';
|
||||
|
||||
fs_mgmt_pm_unlink(write_ctx.filename);
|
||||
|
||||
fs_mgmt_pm_unlink(write_ctx.filename);
|
||||
rc = fs_mgmt_pm_open(&write_ctx.file, write_ctx.filename, FS_O_CREATE | FS_O_WRITE);
|
||||
|
||||
if (rc == 0) {
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
write_ctx.state = FS_STATE_RECEIVING_FILE;
|
||||
write_ctx.crc32 = 0;
|
||||
write_ctx.unacked_chunks = 0;
|
||||
LOG_INF("File transfer started: %s (Expected: %u bytes)", write_ctx.filename, msg.metadata);
|
||||
|
||||
uint16_t credits = buzz_proto_get_free_rx_slabs();
|
||||
|
||||
uint16_t credits = MIN(INITIAL_CREDITS, buzz_proto_get_free_rx_slabs());
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
buzz_proto_send_ack(msg.reply_cb, credits);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR("Failed to open %s: %d", write_ctx.filename, rc);
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, abs(rc), msg.slab_ptr);
|
||||
}
|
||||
}/* Innerhalb von case FS_STATE_IDLE: */
|
||||
} /* Innerhalb von case FS_STATE_IDLE: */
|
||||
else if (msg.op == FS_WRITE_OP_TAGS_START)
|
||||
{
|
||||
if (msg.data_len >= sizeof(write_ctx.filename)) {
|
||||
if (msg.data_len >= sizeof(write_ctx.filename))
|
||||
{
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, ENAMETOOLONG, msg.slab_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
memcpy(write_ctx.filename, msg.slab_ptr + msg.data_offset, msg.data_len);
|
||||
write_ctx.filename[msg.data_len] = '\0';
|
||||
|
||||
|
||||
/* Datei öffnen: Nur Lese- und Schreibrechte, Datei muss bereits existieren */
|
||||
int rc = fs_mgmt_pm_open(&write_ctx.file, write_ctx.filename, FS_O_READ | FS_O_WRITE);
|
||||
|
||||
if (rc == 0) {
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
ssize_t audio_len = fs_get_audio_data_len(&write_ctx.file);
|
||||
|
||||
if (audio_len < 0) {
|
||||
|
||||
if (audio_len < 0)
|
||||
{
|
||||
LOG_ERR("Failed to get audio length: %d", (int)audio_len);
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, EIO, msg.slab_ptr);
|
||||
@@ -573,7 +584,8 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
|
||||
/* Datei ab dem Ende der Audiodaten abschneiden (alte Tags entfernen) */
|
||||
rc = fs_truncate(&write_ctx.file, audio_len);
|
||||
if (rc != 0) {
|
||||
if (rc != 0)
|
||||
{
|
||||
LOG_ERR("Failed to truncate file: %d", rc);
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, abs(rc), msg.slab_ptr);
|
||||
@@ -587,17 +599,20 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
write_ctx.crc32 = 0;
|
||||
write_ctx.unacked_chunks = 0;
|
||||
write_ctx.audio_len = audio_len;
|
||||
|
||||
|
||||
LOG_INF("Tags transfer started: %s (Expected tags: %u bytes)", write_ctx.filename, msg.metadata);
|
||||
|
||||
|
||||
uint16_t credits = buzz_proto_get_free_rx_slabs();
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
buzz_proto_send_ack(msg.reply_cb, credits);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR("Failed to open %s for tags: %d", write_ctx.filename, rc);
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, abs(rc), msg.slab_ptr);
|
||||
}
|
||||
} else if ( msg.op == FS_WRITE_OP_FW_START)
|
||||
}
|
||||
else if (msg.op == FS_WRITE_OP_FW_START)
|
||||
{
|
||||
LOG_WRN("Operation not yet fully implemented in FS state machine");
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, ENOSYS, msg.slab_ptr);
|
||||
@@ -608,20 +623,25 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
if (msg.op == FS_WRITE_OP_FILE_CHUNK && msg.slab_ptr)
|
||||
{
|
||||
ssize_t written = fs_write(&write_ctx.file, msg.slab_ptr + msg.data_offset, msg.data_len);
|
||||
|
||||
if (written == msg.data_len) {
|
||||
|
||||
if (written == msg.data_len)
|
||||
{
|
||||
write_ctx.crc32 = crc32_ieee_update(write_ctx.crc32, msg.slab_ptr + msg.data_offset, msg.data_len);
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
write_ctx.unacked_chunks++;
|
||||
if (write_ctx.unacked_chunks >= ACK_WATERMARK) {
|
||||
if (write_ctx.unacked_chunks >= ACK_WATERMARK)
|
||||
{
|
||||
uint16_t free_slabs = buzz_proto_get_free_rx_slabs();
|
||||
uint16_t credits_to_send = MIN(free_slabs, write_ctx.unacked_chunks);
|
||||
if (credits_to_send > 0) {
|
||||
if (credits_to_send > 0)
|
||||
{
|
||||
buzz_proto_send_ack(msg.reply_cb, credits_to_send);
|
||||
write_ctx.unacked_chunks -= credits_to_send;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR("Flash write failed!");
|
||||
write_ctx.state = FS_STATE_IDLE;
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, EIO, msg.slab_ptr);
|
||||
@@ -631,11 +651,14 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
{
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
write_ctx.state = FS_STATE_IDLE;
|
||||
|
||||
if (write_ctx.crc32 == msg.metadata) {
|
||||
|
||||
if (write_ctx.crc32 == msg.metadata)
|
||||
{
|
||||
LOG_INF("File transfer finished. CRC valid: 0x%08X", write_ctx.crc32);
|
||||
buzz_proto_send_success_reusing_slab(msg.reply_cb, BUZZ_DATA_FILE_PUT, msg.slab_ptr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR("CRC Mismatch! Expected: 0x%08X, Got: 0x%08X", msg.metadata, write_ctx.crc32);
|
||||
fs_mgmt_pm_unlink(write_ctx.filename);
|
||||
buzz_proto_send_error_reusing_slab(msg.reply_cb, EBADMSG, msg.slab_ptr);
|
||||
@@ -646,29 +669,35 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
fs_mgmt_pm_unlink(write_ctx.filename);
|
||||
write_ctx.state = FS_STATE_IDLE;
|
||||
if (msg.slab_ptr) buzz_proto_buf_free(&msg.slab_ptr);
|
||||
if (msg.slab_ptr)
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FS_STATE_RECEIVING_TAGS:
|
||||
|
||||
case FS_STATE_RECEIVING_TAGS:
|
||||
if (msg.op == FS_WRITE_OP_FILE_CHUNK && msg.slab_ptr)
|
||||
{
|
||||
ssize_t written = fs_write(&write_ctx.file, msg.slab_ptr + msg.data_offset, msg.data_len);
|
||||
|
||||
if (written == msg.data_len) {
|
||||
|
||||
if (written == msg.data_len)
|
||||
{
|
||||
write_ctx.crc32 = crc32_ieee_update(write_ctx.crc32, msg.slab_ptr + msg.data_offset, msg.data_len);
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
|
||||
|
||||
write_ctx.unacked_chunks++;
|
||||
if (write_ctx.unacked_chunks >= ACK_WATERMARK) {
|
||||
if (write_ctx.unacked_chunks >= ACK_WATERMARK)
|
||||
{
|
||||
uint16_t free_slabs = buzz_proto_get_free_rx_slabs();
|
||||
uint16_t credits_to_send = MIN(free_slabs, write_ctx.unacked_chunks);
|
||||
if (credits_to_send > 0) {
|
||||
if (credits_to_send > 0)
|
||||
{
|
||||
buzz_proto_send_ack(msg.reply_cb, credits_to_send);
|
||||
write_ctx.unacked_chunks -= credits_to_send;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR("Flash write failed during tags transfer!");
|
||||
fs_truncate(&write_ctx.file, write_ctx.audio_len); /* Rollback */
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
@@ -678,11 +707,14 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
}
|
||||
else if (msg.op == FS_WRITE_OP_FILE_END)
|
||||
{
|
||||
if (write_ctx.crc32 == msg.metadata) {
|
||||
if (write_ctx.crc32 == msg.metadata)
|
||||
{
|
||||
LOG_INF("Tags transfer finished. CRC valid: 0x%08X", write_ctx.crc32);
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
buzz_proto_send_success_reusing_slab(msg.reply_cb, BUZZ_DATA_TAGS_PUT, msg.slab_ptr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERR("Tags CRC Mismatch! Expected: 0x%08X, Got: 0x%08X", msg.metadata, write_ctx.crc32);
|
||||
fs_truncate(&write_ctx.file, write_ctx.audio_len); /* Rollback */
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
@@ -695,20 +727,22 @@ static void fs_thread_entry(void *p1, void *p2, void *p3)
|
||||
fs_truncate(&write_ctx.file, write_ctx.audio_len); /* Rollback */
|
||||
fs_mgmt_pm_close(&write_ctx.file);
|
||||
write_ctx.state = FS_STATE_IDLE;
|
||||
if (msg.slab_ptr) buzz_proto_buf_free(&msg.slab_ptr);
|
||||
if (msg.slab_ptr)
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case FS_STATE_RECEIVING_FIRMWARE:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Garbage Collection: Ungültige Operationen im falschen State abfangen */
|
||||
if (write_ctx.state == FS_STATE_IDLE && msg.op == FS_WRITE_OP_FILE_CHUNK && msg.slab_ptr) {
|
||||
if (write_ctx.state == FS_STATE_IDLE && msg.op == FS_WRITE_OP_FILE_CHUNK && msg.slab_ptr)
|
||||
{
|
||||
buzz_proto_buf_free(&msg.slab_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
K_THREAD_DEFINE(fs_thread, CONFIG_FS_MGMT_THREAD_STACK_SIZE, fs_thread_entry,
|
||||
K_THREAD_DEFINE(fs_thread, CONFIG_FS_MGMT_THREAD_STACK_SIZE, fs_thread_entry,
|
||||
NULL, NULL, NULL, CONFIG_FS_MGMT_THREAD_PRIORITY, 0, 0);
|
||||
Reference in New Issue
Block a user