zwischenstand
This commit is contained in:
@@ -28,34 +28,34 @@ if BLE_MGMT
|
||||
help
|
||||
Maximal advertising interval. 160 equals to 100ms.
|
||||
|
||||
config BT_L2CAP_TX_MTU
|
||||
default 247
|
||||
config BT_BUF_ACL_RX_SIZE
|
||||
default 251
|
||||
config BT_BUF_ACL_TX_SIZE
|
||||
default 251
|
||||
config BT_CTLR_DATA_LENGTH_MAX
|
||||
default 251
|
||||
config BT_USER_DATA_LEN_UPDATE
|
||||
default y
|
||||
config BT_USER_PHY_UPDATE
|
||||
default y
|
||||
config BT_HCI_ACL_FLOW_CONTROL
|
||||
default y
|
||||
config BT_BUF_CMD_TX_COUNT
|
||||
default 24
|
||||
config BT_BUF_EVT_RX_COUNT
|
||||
default 22
|
||||
config BT_BUF_ACL_TX_COUNT
|
||||
default 20
|
||||
config BT_L2CAP_TX_BUF_COUNT
|
||||
default 20
|
||||
config BT_CONN_TX_MAX
|
||||
default 20
|
||||
config BT_CTLR_SDC_TX_PACKET_COUNT
|
||||
default 20
|
||||
config BT_CTLR_SDC_RX_PACKET_COUNT
|
||||
default 20
|
||||
# config BT_L2CAP_TX_MTU
|
||||
# default 247
|
||||
# config BT_BUF_ACL_RX_SIZE
|
||||
# default 251
|
||||
# config BT_BUF_ACL_TX_SIZE
|
||||
# default 251
|
||||
# config BT_CTLR_DATA_LENGTH_MAX
|
||||
# default 251
|
||||
# config BT_USER_DATA_LEN_UPDATE
|
||||
# default y
|
||||
# config BT_USER_PHY_UPDATE
|
||||
# default y
|
||||
# config BT_HCI_ACL_FLOW_CONTROL
|
||||
# default y
|
||||
# config BT_BUF_CMD_TX_COUNT
|
||||
# default 24
|
||||
# config BT_BUF_EVT_RX_COUNT
|
||||
# default 22
|
||||
# config BT_BUF_ACL_TX_COUNT
|
||||
# default 20
|
||||
# config BT_L2CAP_TX_BUF_COUNT
|
||||
# default 20
|
||||
# config BT_CONN_TX_MAX
|
||||
# default 20
|
||||
# config BT_CTLR_SDC_TX_PACKET_COUNT
|
||||
# default 20
|
||||
# config BT_CTLR_SDC_RX_PACKET_COUNT
|
||||
# default 20
|
||||
config BT_MAX_CONN
|
||||
default 2
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ble_mgmt.h"
|
||||
@@ -24,7 +26,9 @@ static struct bt_uuid_128 buzz_tx_uuid = BT_UUID_INIT_128(BUZZ_TX_UUID_VAL);
|
||||
|
||||
static ble_mgmt_rx_cb_t app_rx_cb = NULL;
|
||||
static bool notify_enabled = false;
|
||||
|
||||
static uint16_t current_tx_mtu = 23;
|
||||
static uint16_t current_rx_mtu = 23;
|
||||
|
||||
#define MAX_ADV_NAME_LEN 29
|
||||
static char current_device_name[MAX_ADV_NAME_LEN + 1];
|
||||
@@ -52,6 +56,7 @@ static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
|
||||
{
|
||||
LOG_INF("MTU exchanged: TX %u bytes, RX %u bytes", tx, rx);
|
||||
current_tx_mtu = tx;
|
||||
current_rx_mtu = rx;
|
||||
}
|
||||
|
||||
static ssize_t rx_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
@@ -59,8 +64,9 @@ static ssize_t rx_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
{
|
||||
LOG_DBG("Received %u bytes", len);
|
||||
LOG_HEXDUMP_DBG(buf, len, "Data:");
|
||||
|
||||
if (app_rx_cb) {
|
||||
|
||||
if (app_rx_cb)
|
||||
{
|
||||
app_rx_cb((const uint8_t *)buf, len);
|
||||
}
|
||||
return len;
|
||||
@@ -69,25 +75,25 @@ static ssize_t rx_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
static void tx_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
notify_enabled = (value == BT_GATT_CCC_NOTIFY);
|
||||
LOG_DBG("Notifications %s", notify_enabled ? "enabled" : "disabled");
|
||||
LOG_INF("Notifications %s", notify_enabled ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
BT_GATT_SERVICE_DEFINE(ble_mgmt_svc,
|
||||
BT_GATT_PRIMARY_SERVICE(&buzz_service_uuid),
|
||||
BT_GATT_CHARACTERISTIC(&buzz_rx_uuid.uuid, BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||
BT_GATT_PERM_WRITE, NULL, rx_cb, NULL),
|
||||
BT_GATT_CHARACTERISTIC(&buzz_tx_uuid.uuid, BT_GATT_CHRC_NOTIFY,
|
||||
BT_GATT_PERM_NONE, NULL, NULL, NULL),
|
||||
BT_GATT_CCC(tx_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)
|
||||
);
|
||||
BT_GATT_PRIMARY_SERVICE(&buzz_service_uuid),
|
||||
BT_GATT_CHARACTERISTIC(&buzz_rx_uuid.uuid, BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||
BT_GATT_PERM_WRITE, NULL, rx_cb, NULL),
|
||||
BT_GATT_CHARACTERISTIC(&buzz_tx_uuid.uuid, BT_GATT_CHRC_NOTIFY,
|
||||
BT_GATT_PERM_NONE, NULL, NULL, NULL),
|
||||
BT_GATT_CCC(tx_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE));
|
||||
|
||||
uint16_t ble_mgmt_get_max_payload(void)
|
||||
{
|
||||
/* Kappe die verhandelte MTU auf die hart konfigurierte Zephyr-Puffergrenze */
|
||||
uint16_t effective_mtu = current_tx_mtu;
|
||||
|
||||
uint16_t effective_mtu = MIN(current_tx_mtu, current_rx_mtu);
|
||||
|
||||
#ifdef CONFIG_BT_L2CAP_TX_MTU
|
||||
if (effective_mtu > CONFIG_BT_L2CAP_TX_MTU) {
|
||||
if (effective_mtu > CONFIG_BT_L2CAP_TX_MTU)
|
||||
{
|
||||
effective_mtu = CONFIG_BT_L2CAP_TX_MTU;
|
||||
}
|
||||
#endif
|
||||
@@ -98,19 +104,23 @@ uint16_t ble_mgmt_get_max_payload(void)
|
||||
|
||||
int ble_mgmt_send(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
if (!notify_enabled) {
|
||||
if (!notify_enabled)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
int rc;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
rc = bt_gatt_notify(NULL, &ble_mgmt_svc.attrs[4], data, len);
|
||||
if (rc == -ENOMEM) {
|
||||
if (rc == -ENOMEM)
|
||||
{
|
||||
k_sleep(K_MSEC(5)); // Thread pausieren, bis TX-Buffer frei wird
|
||||
}
|
||||
} while (rc == -ENOMEM);
|
||||
|
||||
if (rc) {
|
||||
if (rc)
|
||||
{
|
||||
LOG_ERR("Failed to send notification (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
@@ -120,13 +130,14 @@ int ble_mgmt_send(const uint8_t *data, uint16_t len)
|
||||
/* Interne Hilfsfunktion zur Zuweisung des Namens */
|
||||
static void set_device_name(const char *name)
|
||||
{
|
||||
if (!name) {
|
||||
if (!name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
strncpy(current_device_name, name, MAX_ADV_NAME_LEN);
|
||||
current_device_name[MAX_ADV_NAME_LEN] = '\0';
|
||||
|
||||
|
||||
/* Längen-Update im Scan-Response Array */
|
||||
sd[0].data_len = strlen(current_device_name);
|
||||
|
||||
@@ -144,7 +155,8 @@ int ble_mgmt_update_adv_name(const char *new_name)
|
||||
set_device_name(new_name);
|
||||
|
||||
rc = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
|
||||
if (rc) {
|
||||
if (rc)
|
||||
{
|
||||
LOG_ERR("Advertising failed to restart after name update (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
@@ -153,40 +165,10 @@ int ble_mgmt_update_adv_name(const char *new_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_mgmt_init(ble_mgmt_rx_cb_t rx_cb, const char *device_name)
|
||||
{
|
||||
int rc;
|
||||
|
||||
app_rx_cb = rx_cb;
|
||||
|
||||
static struct bt_gatt_cb gatt_callbacks = {
|
||||
.att_mtu_updated = att_mtu_updated,
|
||||
};
|
||||
|
||||
bt_gatt_cb_register(&gatt_callbacks);
|
||||
|
||||
rc = bt_enable(NULL);
|
||||
if (rc) {
|
||||
LOG_ERR("Bluetooth init failed (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
const char *name_to_use = (device_name != NULL) ? device_name : CONFIG_BLE_MGMT_DEFAULT_DEVICE_NAME;
|
||||
set_device_name(name_to_use);
|
||||
|
||||
rc = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
|
||||
if (rc) {
|
||||
LOG_ERR("Advertising failed to start (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
LOG_INF("Bluetooth initialized. Adv-Name: %s", current_device_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void connected(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
if (err) {
|
||||
if (err)
|
||||
{
|
||||
LOG_ERR("Connection failed (err 0x%02x)", err);
|
||||
return;
|
||||
}
|
||||
@@ -195,50 +177,38 @@ static void connected(struct bt_conn *conn, uint8_t err)
|
||||
struct bt_conn_info info;
|
||||
|
||||
int rc = bt_conn_get_info(conn, &info);
|
||||
if (rc == 0) {
|
||||
if (rc == 0)
|
||||
{
|
||||
bt_addr_le_to_str(info.le.dst, addr_str, sizeof(addr_str));
|
||||
LOG_INF("Connected to %s", addr_str);
|
||||
|
||||
/* Nur noch die Rolle ausgeben, da Timing-Parameter hier deprecated sind */
|
||||
LOG_DBG("Role: %s", info.role == BT_CONN_ROLE_CENTRAL ? "Central" : "Peripheral");
|
||||
} else {
|
||||
LOG_INF("Role: %s", info.role == BT_CONN_ROLE_CENTRAL ? "Central" : "Peripheral");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INF("Connected (info retrieval failed)");
|
||||
}
|
||||
struct bt_conn_le_phy_param phy_param = {
|
||||
.options = BT_CONN_LE_PHY_OPT_NONE,
|
||||
.pref_tx_phy = BT_GAP_LE_PHY_2M,
|
||||
.pref_rx_phy = BT_GAP_LE_PHY_2M,
|
||||
};
|
||||
rc = bt_conn_le_phy_update(conn, &phy_param);
|
||||
if (rc) {
|
||||
LOG_WRN("PHY update failed (err %d)", rc);
|
||||
}
|
||||
struct bt_le_conn_param *param = BT_LE_CONN_PARAM(12, 24, 0, 400);
|
||||
rc = bt_conn_le_param_update(conn, param);
|
||||
if (rc) {
|
||||
LOG_WRN("Connection update failed (err %d)", rc);
|
||||
}
|
||||
}
|
||||
|
||||
static void disconnected(struct bt_conn *conn, uint8_t reason)
|
||||
{
|
||||
LOG_DBG("Disconnected (reason 0x%02x)", reason);
|
||||
LOG_INF("Disconnected (reason 0x%02x)", reason);
|
||||
|
||||
/* Startet Advertising mit dem global definierten Setup neu */
|
||||
int rc = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
|
||||
if (rc) {
|
||||
if (rc)
|
||||
{
|
||||
LOG_ERR("Advertising failed to restart (err %d)", rc);
|
||||
} else {
|
||||
LOG_DBG("Advertising successfully restarted");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INF("Advertising successfully restarted");
|
||||
}
|
||||
}
|
||||
|
||||
static void le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param)
|
||||
{
|
||||
const char *tx_phy_str = (param->tx_phy == BT_GAP_LE_PHY_2M) ? "2M" :
|
||||
(param->tx_phy == BT_GAP_LE_PHY_1M) ? "1M" : "Coded/Unknown";
|
||||
const char *rx_phy_str = (param->rx_phy == BT_GAP_LE_PHY_2M) ? "2M" :
|
||||
(param->rx_phy == BT_GAP_LE_PHY_1M) ? "1M" : "Coded/Unknown";
|
||||
const char *tx_phy_str = (param->tx_phy == BT_GAP_LE_PHY_2M) ? "2M" : (param->tx_phy == BT_GAP_LE_PHY_1M) ? "1M" : "Coded/Unknown";
|
||||
const char *rx_phy_str = (param->rx_phy == BT_GAP_LE_PHY_2M) ? "2M" : (param->rx_phy == BT_GAP_LE_PHY_1M) ? "1M" : "Coded/Unknown";
|
||||
|
||||
LOG_INF("LE PHY updated: TX PHY %s, RX PHY %s", tx_phy_str, rx_phy_str);
|
||||
}
|
||||
@@ -256,3 +226,35 @@ BT_CONN_CB_DEFINE(conn_callbacks) = {
|
||||
.le_param_updated = le_param_updated,
|
||||
.le_phy_updated = le_phy_updated,
|
||||
};
|
||||
|
||||
int ble_mgmt_init(ble_mgmt_rx_cb_t rx_cb, const char *device_name)
|
||||
{
|
||||
int rc;
|
||||
app_rx_cb = rx_cb;
|
||||
|
||||
static struct bt_gatt_cb gatt_callbacks = {
|
||||
.att_mtu_updated = att_mtu_updated,
|
||||
};
|
||||
|
||||
bt_gatt_cb_register(&gatt_callbacks);
|
||||
|
||||
rc = bt_enable(NULL);
|
||||
if (rc)
|
||||
{
|
||||
LOG_ERR("Bluetooth init failed (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
const char *name_to_use = (device_name != NULL) ? device_name : CONFIG_BLE_MGMT_DEFAULT_DEVICE_NAME;
|
||||
set_device_name(name_to_use);
|
||||
|
||||
rc = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
|
||||
if (rc)
|
||||
{
|
||||
LOG_ERR("Advertising failed to start (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
LOG_INF("Bluetooth initialized. Adv-Name: %s", current_device_name);
|
||||
return 0;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ menuconfig BUZZ_PROTO
|
||||
|
||||
config BUZZ_PROTO_SLAB_SIZE
|
||||
int "Slab Size"
|
||||
default 256
|
||||
default 512
|
||||
help
|
||||
Size of the memory slabs used for message buffers. Must be large enough to hold the largest expected message.
|
||||
|
||||
@@ -18,7 +18,7 @@ menuconfig BUZZ_PROTO
|
||||
|
||||
config BUZZ_PROTO_MSGQ_SIZE
|
||||
int "Message Queue Size"
|
||||
default 16
|
||||
default 64
|
||||
help
|
||||
Number of messages that can be queued for processing. Adjust based on expected message burstiness.
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -8,7 +8,6 @@ CONFIG_FS_LOG_LEVEL_WRN=y
|
||||
|
||||
### Bluetooth
|
||||
CONFIG_BLE_MGMT=y
|
||||
# CONFIG_BLE_MGMT_LOG_LEVEL_DBG=y
|
||||
|
||||
# Advertising 500ms - 1s
|
||||
CONFIG_BLE_MGMT_ADV_INT_MIN=160
|
||||
@@ -23,4 +22,36 @@ CONFIG_PM_DEVICE=y
|
||||
|
||||
## Shell
|
||||
# CONFIG_SHELL=y
|
||||
# CONFIG_FILE_SYSTEM_SHELL=y
|
||||
# CONFIG_FILE_SYSTEM_SHELL=y
|
||||
|
||||
# Airtime-Maximierung
|
||||
CONFIG_BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=4000000
|
||||
|
||||
# MTU-Setup
|
||||
CONFIG_BT_BUF_ACL_RX_SIZE=502
|
||||
CONFIG_BT_BUF_ACL_TX_SIZE=502
|
||||
CONFIG_BT_L2CAP_TX_MTU=498
|
||||
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
|
||||
|
||||
# Puffer-Konfiguration (TX = 15, EVT = 16)
|
||||
CONFIG_BT_BUF_ACL_TX_COUNT=15
|
||||
CONFIG_BT_L2CAP_TX_BUF_COUNT=15
|
||||
CONFIG_BT_CONN_TX_MAX=15
|
||||
CONFIG_BT_CTLR_SDC_TX_PACKET_COUNT=15
|
||||
CONFIG_BT_CTLR_SDC_RX_PACKET_COUNT=15
|
||||
CONFIG_BT_BUF_EVT_RX_COUNT=16
|
||||
|
||||
# WICHTIG: Diese Flags aktivieren die Callbacks in der bt_conn_cb Struktur
|
||||
CONFIG_BT_USER_PHY_UPDATE=y
|
||||
CONFIG_BT_USER_DATA_LEN_UPDATE=y
|
||||
|
||||
# Automatische Updates im Hintergrund aktivieren
|
||||
CONFIG_BT_AUTO_PHY_UPDATE=y
|
||||
CONFIG_BT_AUTO_DATA_LEN_UPDATE=y
|
||||
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=y
|
||||
|
||||
# Bevorzugte Parameter für das Auto-Update definieren (entspricht BT_LE_CONN_PARAM(12, 36, 0, 400))
|
||||
CONFIG_BT_PERIPHERAL_PREF_MIN_INT=12
|
||||
CONFIG_BT_PERIPHERAL_PREF_MAX_INT=40
|
||||
CONFIG_BT_PERIPHERAL_PREF_LATENCY=0
|
||||
CONFIG_BT_PERIPHERAL_PREF_TIMEOUT=400
|
||||
@@ -13,8 +13,8 @@ void ble_rx_cb(const uint8_t *data, uint16_t len)
|
||||
uint8_t *buf;
|
||||
|
||||
/* 1. Länge prüfen (darf SLAB_BLOCK_SIZE = 256 nicht überschreiten) */
|
||||
if (len > 256) {
|
||||
LOG_ERR("Received data too large for proto buf (%u bytes)", len);
|
||||
if (len > CONFIG_BUZZ_PROTO_SLAB_SIZE) {
|
||||
LOG_ERR("Received data too large for proto buf (%u > %u)", len, CONFIG_BUZZ_PROTO_SLAB_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user