feat(app): 添加蓝牙电量模块支持
- 在CMakeLists.txt中添加ble_battery_module.c源文件 - 实现BLE电池服务模块,提供电池电量GATT服务 - 支持电池电量读取和通知功能 - 集成到应用事件管理器,监听电池状态事件 - 当蓝牙连接就绪时设置模块状态为READY
This commit is contained in:
@@ -25,6 +25,7 @@ target_sources(app PRIVATE
|
|||||||
src/events/mode_event.c
|
src/events/mode_event.c
|
||||||
src/modules/battery_module.c
|
src/modules/battery_module.c
|
||||||
src/modules/ble_adv_ctrl_module.c
|
src/modules/ble_adv_ctrl_module.c
|
||||||
|
src/modules/ble_battery_module.c
|
||||||
src/modules/ble_bond_module.c
|
src/modules/ble_bond_module.c
|
||||||
src/modules/keyboard_module.c
|
src/modules/keyboard_module.c
|
||||||
src/modules/led_state_module.c
|
src/modules/led_state_module.c
|
||||||
|
|||||||
91
src/modules/ble_battery_module.c
Normal file
91
src/modules/ble_battery_module.c
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/bluetooth/gatt.h>
|
||||||
|
|
||||||
|
#include <app_event_manager.h>
|
||||||
|
|
||||||
|
#define MODULE ble_battery
|
||||||
|
#include <caf/events/module_state_event.h>
|
||||||
|
|
||||||
|
#include "battery_status_event.h"
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
static bool notify_enabled;
|
||||||
|
static uint8_t battery_level = 100U;
|
||||||
|
|
||||||
|
static void bas_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(attr);
|
||||||
|
notify_enabled = (value == BT_GATT_CCC_NOTIFY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t read_battery_level(struct bt_conn *conn,
|
||||||
|
const struct bt_gatt_attr *attr,
|
||||||
|
void *buf,
|
||||||
|
uint16_t len,
|
||||||
|
uint16_t offset)
|
||||||
|
{
|
||||||
|
const uint8_t *value = attr->user_data;
|
||||||
|
|
||||||
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_GATT_SERVICE_DEFINE(ble_battery_svc,
|
||||||
|
BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS),
|
||||||
|
BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL,
|
||||||
|
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
||||||
|
BT_GATT_PERM_READ_ENCRYPT,
|
||||||
|
read_battery_level, NULL, &battery_level),
|
||||||
|
BT_GATT_CCC(bas_ccc_cfg_changed,
|
||||||
|
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||||
|
);
|
||||||
|
|
||||||
|
static bool handle_battery_status_event(const struct battery_status_event *event)
|
||||||
|
{
|
||||||
|
battery_level = event->soc;
|
||||||
|
|
||||||
|
if (!notify_enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = bt_gatt_notify(NULL, &ble_battery_svc.attrs[1], &battery_level, sizeof(battery_level));
|
||||||
|
|
||||||
|
if (err == -ENOTCONN) {
|
||||||
|
LOG_WRN("BAS notify skipped: peer disconnecting");
|
||||||
|
} else if (err) {
|
||||||
|
LOG_ERR("BAS notify failed: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_module_state_event(const struct module_state_event *event)
|
||||||
|
{
|
||||||
|
if (!check_state(event, MODULE_ID(ble_state), MODULE_STATE_READY)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_set_state(MODULE_STATE_READY);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool app_event_handler(const struct app_event_header *aeh)
|
||||||
|
{
|
||||||
|
if (is_battery_status_event(aeh)) {
|
||||||
|
return handle_battery_status_event(cast_battery_status_event(aeh));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_module_state_event(aeh)) {
|
||||||
|
return handle_module_state_event(cast_module_state_event(aeh));
|
||||||
|
}
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, battery_status_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
Reference in New Issue
Block a user