blob: 18c03110f2b97ff2e666e7b70e7fc589854c4caa [file] [log] [blame]
/* Common functions for LE Audio services */
/*
* Copyright (c) 2022 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/audio/audio.h>
#include "audio_internal.h"
static uint8_t bt_audio_security_check(const struct bt_conn *conn)
{
struct bt_conn_info info;
int err;
err = bt_conn_get_info(conn, &info);
if (err < 0) {
return BT_ATT_ERR_UNLIKELY;
}
/* Require an encryption key with at least 128 bits of entropy, derived from SC or OOB
* method.
*/
if ((info.security.flags & (BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC)) == 0) {
/* If the client has insufficient security to read/write the requested attribute
* then an ATT_ERROR_RSP PDU shall be sent with the Error Code parameter set to
* Insufficient Authentication (0x05).
*/
return BT_ATT_ERR_AUTHENTICATION;
}
if (info.security.enc_key_size < BT_ENC_KEY_SIZE_MAX) {
return BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
}
return BT_ATT_ERR_SUCCESS;
}
ssize_t bt_audio_read_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
{
const struct bt_audio_attr_user_data *user_data = attr->user_data;
if (user_data->read == NULL) {
return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
}
if (conn != NULL) {
uint8_t err;
err = bt_audio_security_check(conn);
if (err != 0) {
return BT_GATT_ERR(err);
}
}
return user_data->read(conn, attr, buf, len, offset);
}
ssize_t bt_audio_write_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
const struct bt_audio_attr_user_data *user_data = attr->user_data;
if (user_data->write == NULL) {
return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
}
if (conn != NULL) {
uint8_t err;
err = bt_audio_security_check(conn);
if (err != 0) {
return BT_GATT_ERR(err);
}
}
return user_data->write(conn, attr, buf, len, offset, flags);
}
ssize_t bt_audio_ccc_cfg_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
uint16_t value)
{
if (conn != NULL) {
uint8_t err;
err = bt_audio_security_check(conn);
if (err != 0) {
return BT_GATT_ERR(err);
}
}
return sizeof(value);
}