99 lines
2.7 KiB
C
99 lines
2.7 KiB
C
/*
|
|
* Copyright (c) 2024 Demant A/S
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/bluetooth/services/bas.h>
|
|
#include <zephyr/bluetooth/gatt.h>
|
|
#include "bas_internal.h"
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(bas, CONFIG_BT_BAS_LOG_LEVEL);
|
|
|
|
#define BATTERY_CRITICAL_STATUS_CHAR_IDX 9
|
|
|
|
static uint8_t battery_critical_status;
|
|
|
|
void bt_bas_bcs_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
|
{
|
|
ARG_UNUSED(attr);
|
|
|
|
bool ind_enabled = (value == BT_GATT_CCC_INDICATE);
|
|
|
|
LOG_DBG("BAS Critical status Indication %s", ind_enabled ? "enabled" : "disabled");
|
|
}
|
|
|
|
ssize_t bt_bas_bcs_read_critical_status(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
|
void *buf, uint16_t len, uint16_t offset)
|
|
{
|
|
|
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, &battery_critical_status,
|
|
sizeof(uint8_t));
|
|
}
|
|
|
|
static void bcs_indicate_cb(struct bt_conn *conn, struct bt_gatt_indicate_params *params,
|
|
uint8_t err)
|
|
{
|
|
if (err != 0) {
|
|
LOG_DBG("BCS Indication failed with error %u\n", err);
|
|
} else {
|
|
LOG_DBG("BCS Indication sent successfully\n");
|
|
}
|
|
}
|
|
|
|
static void bt_bas_bcs_update_battery_critical_status(void)
|
|
{
|
|
/* Indicate all connections */
|
|
const struct bt_gatt_attr *attr = bt_bas_get_bas_attr(BATTERY_CRITICAL_STATUS_CHAR_IDX);
|
|
|
|
if (attr) {
|
|
uint8_t err;
|
|
/* Indicate battery critical status to all connections */
|
|
static struct bt_gatt_indicate_params bcs_ind_params;
|
|
|
|
bcs_ind_params.attr = attr;
|
|
bcs_ind_params.data = &battery_critical_status;
|
|
bcs_ind_params.len = sizeof(battery_critical_status);
|
|
bcs_ind_params.func = bcs_indicate_cb;
|
|
err = bt_gatt_indicate(NULL, &bcs_ind_params);
|
|
if (err && err != -ENOTCONN) {
|
|
LOG_DBG("Failed to send critical status ind to all conns (err %d)\n", err);
|
|
}
|
|
}
|
|
}
|
|
|
|
void bt_bas_bcs_set_battery_critical_state(bool critical_state)
|
|
{
|
|
bool current_state = (battery_critical_status & BT_BAS_BCS_BATTERY_CRITICAL_STATE) != 0;
|
|
|
|
if (current_state == critical_state) {
|
|
LOG_DBG("Already battery_critical_state is %d\n", critical_state);
|
|
return;
|
|
}
|
|
|
|
if (critical_state) {
|
|
battery_critical_status |= BT_BAS_BCS_BATTERY_CRITICAL_STATE;
|
|
} else {
|
|
battery_critical_status &= ~BT_BAS_BCS_BATTERY_CRITICAL_STATE;
|
|
}
|
|
bt_bas_bcs_update_battery_critical_status();
|
|
}
|
|
|
|
void bt_bas_bcs_set_immediate_service_required(bool service_required)
|
|
{
|
|
bool current_state = (battery_critical_status & BT_BAS_BCS_IMMEDIATE_SERVICE_REQUIRED) != 0;
|
|
|
|
if (current_state == service_required) {
|
|
LOG_DBG("Already immediate_service_required is %d\n", service_required);
|
|
return;
|
|
}
|
|
|
|
if (service_required) {
|
|
battery_critical_status |= BT_BAS_BCS_IMMEDIATE_SERVICE_REQUIRED;
|
|
} else {
|
|
battery_critical_status &= ~BT_BAS_BCS_IMMEDIATE_SERVICE_REQUIRED;
|
|
}
|
|
bt_bas_bcs_update_battery_critical_status();
|
|
}
|