code clean up and persistence for beacon last state

Signed-off-by: Peter Siegmund <mars3142@users.noreply.github.com>
This commit is contained in:
2025-08-29 16:01:25 +02:00
parent 8bf9e8f462
commit 13b009c0db
12 changed files with 139 additions and 88 deletions

View File

@@ -7,4 +7,5 @@ idf_component_register(SRCS
esp_driver_gpio
esp_driver_gptimer
esp_driver_ledc
persistence
)

View File

@@ -6,6 +6,7 @@
#include "freertos/task.h"
#include "led_strip.h"
#include "light.h"
#include "persistence.h"
#include "sdkconfig.h"
#include "semaphore.h"
@@ -84,6 +85,8 @@ esp_err_t beacon_start(void)
{
ESP_LOGI(TAG, "GPTimer started.");
}
ESP_LOGD(TAG, "Beacon started.");
return ret;
}
@@ -110,6 +113,7 @@ esp_err_t beacon_stop(void)
{
ESP_LOGE(TAG, "Failed to enable gptimer: %s", esp_err_to_name(ret));
}
return ret;
}

View File

@@ -1,4 +1,5 @@
idf_component_register(SRCS
"char_desc.c"
"device_service.c"
"light_service.c"
"remote_control.c"
@@ -8,4 +9,5 @@ idf_component_register(SRCS
bt
esp_app_format
light
persistence
)

View File

@@ -0,0 +1,31 @@
#include "char_desc.h"
int gatt_svr_desc_presentation_bool_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC)
{
// 7-Byte Format: [format, exponent, unit(2), namespace, description(2)]
uint8_t fmt[7] = {
0x01, // format = boolean
0x00, // exponent
0x00, 0x00, // unit = none
0x01, // namespace = Bluetooth SIG
0x00, 0x00 // description
};
return os_mbuf_append(ctxt->om, fmt, sizeof(fmt)) == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
return BLE_ATT_ERR_READ_NOT_PERMITTED;
}
int gatt_svr_desc_valid_range_bool_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC)
{
// for bool optional. but here as 1-Byte-Min/Max (0..1)
uint8_t range[2] = {0x00, 0x01}; // min=0, max=1
return os_mbuf_append(ctxt->om, range, sizeof(range)) == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
return BLE_ATT_ERR_READ_NOT_PERMITTED;
}

View File

@@ -3,7 +3,8 @@
#include <stdio.h>
#include <string.h>
int device_name_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
int gatt_svr_chr_device_name_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
char firmware_revision_str[33];
const esp_app_desc_t *app_desc = esp_app_get_description();
@@ -21,8 +22,8 @@ int device_name_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_a
return 0;
}
int device_firmware_revision_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
int gatt_svr_chr_device_firmware_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
char firmware_revision_str[33];
const esp_app_desc_t *app_desc = esp_app_get_description();
@@ -40,15 +41,16 @@ int device_firmware_revision_cb(uint16_t conn_handle, uint16_t attr_handle, stru
return 0;
}
int device_hardware_revision_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
int gatt_svr_chr_device_hardware_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
char *hardware_revision = "rev1";
os_mbuf_append(ctxt->om, hardware_revision, strlen(hardware_revision));
return 0;
}
int device_manufacturer_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
int gatt_svr_chr_device_manufacturer_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
char *manufacturer = "mars3142";
os_mbuf_append(ctxt->om, manufacturer, strlen(manufacturer));

View File

@@ -0,0 +1,9 @@
#pragma once
#include "host/ble_gatt.h"
#include <stdint.h>
int gatt_svr_desc_presentation_bool_access(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
int gatt_svr_desc_valid_range_bool_access(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);

View File

@@ -4,15 +4,17 @@
#include <stdio.h>
// 0x2A00 - Device Name
int device_name_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int gatt_svr_chr_device_name_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
// 0x2A26 - Firmware Revision String
int device_firmware_revision_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
int gatt_svr_chr_device_firmware_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
// 0x2A27 - Hardware Revision String
int device_hardware_revision_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
int gatt_svr_chr_device_hardware_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
// 0x2A29 - Manufacturer Name String
int device_manufacturer_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int gatt_svr_chr_device_manufacturer_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);

View File

@@ -4,15 +4,17 @@
#include <stdio.h>
// 0xA000 - Light Service
int led_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int gatt_svr_chr_light_led_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
// 0xBEA0 - Beacon Control
int beacon_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int gatt_svr_chr_light_beacon_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
/// Outdoor Light Descriptors
int led_char_user_desc_cb(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int gatt_svr_desc_led_user_desc_access(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);
/// Beacon Characteristic Descriptors
int beacon_char_user_desc_cb(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int bool_char_presentation_cb(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int bool_char_valid_range_cb(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int gatt_svr_desc_beacon_user_desc_access(uint16_t con_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg);

View File

@@ -19,3 +19,4 @@ extern uint16_t tx_chr_val_handle;
int gatt_svr_chr_uart_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
void send_ble_data(const char *data);
void uart_tx_task(void *param);

View File

@@ -1,12 +1,12 @@
#include "include/light_service.h"
#include "beacon.h"
#include "persistence.h"
static const char *TAG = "light_service";
static uint8_t g_led_enabled = 1; // 0=false, 1=true
static uint8_t g_beacon_enabled = 0;
/// Characteristic Callbacks
int led_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
int gatt_svr_chr_light_led_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR)
{
@@ -17,11 +17,15 @@ int led_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ct
return BLE_ATT_ERR_UNLIKELY;
}
int beacon_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
int gatt_svr_chr_light_beacon_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
persistence_load(VALUE_TYPE_INT32, "BEACON_ENABLED", &g_beacon_enabled);
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR)
{
return os_mbuf_append(ctxt->om, &g_led_enabled, sizeof(g_led_enabled)) == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
return os_mbuf_append(ctxt->om, &g_beacon_enabled, sizeof(g_beacon_enabled)) == 0
? 0
: BLE_ATT_ERR_INSUFFICIENT_RES;
}
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR)
{
@@ -37,14 +41,14 @@ int beacon_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access
return BLE_ATT_ERR_UNLIKELY; // or BLE_ATT_ERR_INVALID_ATTR_VALUE
}
if (val == g_led_enabled) // value is already set
if (val == g_beacon_enabled) // value is already set
{
return 0;
}
g_led_enabled = val;
g_beacon_enabled = val;
if (g_led_enabled)
if (g_beacon_enabled)
{
beacon_start();
}
@@ -52,13 +56,15 @@ int beacon_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access
{
beacon_stop();
}
persistence_save(VALUE_TYPE_INT32, "BEACON_ENABLED", &g_beacon_enabled);
return 0;
}
return BLE_ATT_ERR_UNLIKELY;
}
// Characteristic User Descriptions
int led_char_user_desc_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
int gatt_svr_desc_led_user_desc_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC)
{
@@ -68,7 +74,8 @@ int led_char_user_desc_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble
return BLE_ATT_ERR_READ_NOT_PERMITTED;
}
int beacon_char_user_desc_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
int gatt_svr_desc_beacon_user_desc_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt,
void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC)
{
@@ -77,31 +84,3 @@ int beacon_char_user_desc_cb(uint16_t conn_handle, uint16_t attr_handle, struct
}
return BLE_ATT_ERR_READ_NOT_PERMITTED;
}
int bool_char_presentation_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC)
{
// 7-Byte Format: [format, exponent, unit(2), namespace, description(2)]
uint8_t fmt[7] = {
0x01, // format = boolean
0x00, // exponent
0x00, 0x00, // unit = none
0x01, // namespace = Bluetooth SIG
0x00, 0x00 // description
};
return os_mbuf_append(ctxt->om, fmt, sizeof(fmt)) == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
return BLE_ATT_ERR_READ_NOT_PERMITTED;
}
int bool_char_valid_range_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC)
{
// for bool optional. but here as 1-Byte-Min/Max (0..1)
uint8_t range[2] = {0x00, 0x01}; // min=0, max=1
return os_mbuf_append(ctxt->om, range, sizeof(range)) == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
return BLE_ATT_ERR_READ_NOT_PERMITTED;
}

View File

@@ -11,6 +11,7 @@
#include "host/ble_hs.h"
#include "host/ble_sm.h"
#include "host/ble_uuid.h"
#include "include/char_desc.h"
#include "include/device_service.h"
#include "include/light_service.h"
#include "include/uart_service.h"
@@ -30,41 +31,48 @@ uint8_t ble_addr_type;
static void ble_app_advertise(void);
// Descriptors for the characteristics
static struct ble_gatt_dsc_def led_char_desc[] = {
// Descriptors for the Beacon Characteristic
static struct ble_gatt_dsc_def beacon_char_desc[] = {
{
// User Description Descriptor
.uuid = BLE_UUID16_DECLARE(0x2901),
.att_flags = BLE_ATT_F_READ,
.access_cb = led_char_user_desc_cb,
.access_cb = gatt_svr_desc_beacon_user_desc_access,
},
{
// Presentation Format Descriptor
.uuid = BLE_UUID16_DECLARE(0x2904),
.att_flags = BLE_ATT_F_READ,
.access_cb = bool_char_presentation_cb,
.access_cb = gatt_svr_desc_presentation_bool_access,
},
{
// Valid Range Descriptor
.uuid = BLE_UUID16_DECLARE(0x2906),
.att_flags = BLE_ATT_F_READ,
.access_cb = bool_char_valid_range_cb,
.access_cb = gatt_svr_desc_valid_range_bool_access,
},
{0},
};
static struct ble_gatt_dsc_def beacon_char_desc[] = {
// Descriptors for the LED Characteristic
static struct ble_gatt_dsc_def led_char_desc[] = {
{
// User Description Descriptor
.uuid = BLE_UUID16_DECLARE(0x2901),
.att_flags = BLE_ATT_F_READ,
.access_cb = beacon_char_user_desc_cb,
.access_cb = gatt_svr_desc_led_user_desc_access,
},
{
// Presentation Format Descriptor
.uuid = BLE_UUID16_DECLARE(0x2904),
.att_flags = BLE_ATT_F_READ,
.access_cb = bool_char_presentation_cb,
.access_cb = gatt_svr_desc_presentation_bool_access,
},
{
// Valid Range Descriptor
.uuid = BLE_UUID16_DECLARE(0x2906),
.att_flags = BLE_ATT_F_READ,
.access_cb = bool_char_valid_range_cb,
.access_cb = gatt_svr_desc_valid_range_bool_access,
},
{0},
};
@@ -72,54 +80,63 @@ static struct ble_gatt_dsc_def beacon_char_desc[] = {
// Array of pointers to service definitions
static const struct ble_gatt_svc_def gatt_svcs[] = {
{
// Device Information Service
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &gatt_svr_svc_device_uuid.u,
.characteristics =
(struct ble_gatt_chr_def[]){
{
// Manufacturer String
.uuid = BLE_UUID16_DECLARE(0x2A29),
.flags = BLE_GATT_CHR_F_READ,
.access_cb = device_manufacturer_cb,
.access_cb = gatt_svr_chr_device_manufacturer_access,
},
{
// Hardware Revision String
.uuid = BLE_UUID16_DECLARE(0x2A27),
.flags = BLE_GATT_CHR_F_READ,
.access_cb = device_hardware_revision_cb,
.access_cb = gatt_svr_chr_device_hardware_access,
},
{
// Firmware Revision String
.uuid = BLE_UUID16_DECLARE(0x2A26),
.flags = BLE_GATT_CHR_F_READ,
.access_cb = device_firmware_revision_cb,
.access_cb = gatt_svr_chr_device_firmware_access,
},
{
// Device Name
.uuid = BLE_UUID16_DECLARE(0x2A00),
.flags = BLE_GATT_CHR_F_READ,
.access_cb = device_name_cb,
.access_cb = gatt_svr_chr_device_name_access,
},
{0},
},
},
{
// Light Service
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &gatt_svr_svc_light_uuid.u,
.characteristics =
(struct ble_gatt_chr_def[]){
{
// Beacon Characteristic
.uuid = BLE_UUID16_DECLARE(0xBEA0),
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
.access_cb = beacon_cb,
.access_cb = gatt_svr_chr_light_beacon_access,
.descriptors = beacon_char_desc,
},
{
// LED Characteristic
.uuid = BLE_UUID16_DECLARE(0xF037),
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
.access_cb = led_cb,
.access_cb = gatt_svr_chr_light_led_access,
.descriptors = led_char_desc,
},
{0},
},
},
{
// UART Service
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &gatt_svr_svc_uart_uuid.u,
.characteristics =
@@ -140,6 +157,7 @@ static const struct ble_gatt_svc_def gatt_svcs[] = {
{0},
},
},
// Settings Service (empty for now)
{
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &gatt_svr_svc_settings_uuid.u,
@@ -256,22 +274,6 @@ static void ble_app_on_sync(void)
ble_app_advertise();
}
static void uart_tx_task(void *param)
{
char buffer[50];
int count = 0;
while (1)
{
vTaskDelay(pdMS_TO_TICKS(2000));
if (conn_handle != 0)
{
ESP_LOGI(TAG, "Sending data over BLE UART TX");
sprintf(buffer, "Hello World #%d", count++);
send_ble_data(buffer);
}
}
}
// The infinite task
static void host_task(void *param)
{

View File

@@ -68,3 +68,19 @@ void send_ble_data(const char *data)
}
}
}
void uart_tx_task(void *param)
{
char buffer[50];
int count = 0;
while (1)
{
vTaskDelay(pdMS_TO_TICKS(2000));
if (conn_handle != 0)
{
ESP_LOGI(TAG, "Sending data over BLE UART TX");
sprintf(buffer, "Hello World #%d", count++);
send_ble_data(buffer);
}
}
}