zwischenstand

This commit is contained in:
2026-03-18 15:05:45 +01:00
parent 7c7f19a4b7
commit ff63dda086
29 changed files with 626 additions and 269 deletions

View File

@@ -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;
}