/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include
#include
#include "device_groups.h"
#include "devices.h"
#include "hardware/bt_le_audio.h"
#include "types/raw_address.h"
using bluetooth::le_audio::LeAudioHealthBasedAction;
namespace bluetooth::le_audio {
using LeAudioRecommendationActionCb = base::RepeatingCallback;
/* This should be set by the client of this module to provide information about
* basic LeAudio support of the device which is exposing ASCS UUIDs. Should be
* used with AddStatisticForDevice API
*/
enum class LeAudioHealthDeviceStatType {
/* Should be used whenever LeAudio device has invalid GATT Database structure.
* e.g. missing mandatory services or characteristics. */
INVALID_DB = 0,
/* Should be used when LeAudio devie GATT DB contains at least mandatory
* services and characteristics. */
VALID_DB,
/* Should be used when device expose CSIS support but service is not valid. */
INVALID_CSIS,
/* Should be used when device expose CSIS and Group ID has been
* successfully assigned to device. */
VALID_CSIS,
};
/* When LeAudio device (s) are ready to use, we look at those as a group.
* Using Group stats we measure how good we are in creating streams.
* Should be used with AddStatisticForGroup API
*/
enum class LeAudioHealthGroupStatType {
/* Whenever stream is successfully established. */
STREAM_CREATE_SUCCESS,
/* Whenever stream creation failes due to CIS failures */
STREAM_CREATE_CIS_FAILED,
/* Whenever stream creation failes due to ASCS signaling failures
* e.g. ASE does not go to the proper State on time
*/
STREAM_CREATE_SIGNALING_FAILED,
/* Context stream not available */
STREAM_CONTEXT_NOT_AVAILABLE,
};
class LeAudioHealthStatus {
public:
virtual ~LeAudioHealthStatus(void) = default;
static LeAudioHealthStatus* Get(void);
static void Cleanup(void);
static void DebugDump(int fd);
virtual void RegisterCallback(LeAudioRecommendationActionCb cb) = 0;
virtual void AddStatisticForDevice(const LeAudioDevice* device,
LeAudioHealthDeviceStatType type) = 0;
virtual void AddStatisticForGroup(const LeAudioDeviceGroup* group,
LeAudioHealthGroupStatType type) = 0;
virtual void RemoveStatistics(const RawAddress& address, int group) = 0;
struct group_stats {
group_stats(int group_id)
: group_id_(group_id),
latest_recommendation_(LeAudioHealthBasedAction::NONE),
stream_success_cnt_(0),
stream_failures_cnt_(0),
stream_cis_failures_cnt_(0),
stream_signaling_failures_cnt_(0),
stream_context_not_avail_cnt_(0){};
int group_id_;
LeAudioHealthBasedAction latest_recommendation_;
int stream_success_cnt_;
int stream_failures_cnt_;
int stream_cis_failures_cnt_;
int stream_signaling_failures_cnt_;
int stream_context_not_avail_cnt_;
};
struct device_stats {
device_stats(RawAddress address)
: address_(address),
latest_recommendation_(LeAudioHealthBasedAction::NONE),
is_valid_service_(true),
is_valid_group_member_(true){};
RawAddress address_;
LeAudioHealthBasedAction latest_recommendation_;
bool is_valid_service_;
bool is_valid_group_member_;
};
};
inline std::ostream& operator<<(
std::ostream& os,
const bluetooth::le_audio::LeAudioHealthGroupStatType& stat) {
switch (stat) {
case bluetooth::le_audio::LeAudioHealthGroupStatType::STREAM_CREATE_SUCCESS:
os << "STREAM_CREATE_SUCCESS";
break;
case bluetooth::le_audio::LeAudioHealthGroupStatType::
STREAM_CREATE_CIS_FAILED:
os << "STREAM_CREATE_CIS_FAILED";
break;
case bluetooth::le_audio::LeAudioHealthGroupStatType::
STREAM_CREATE_SIGNALING_FAILED:
os << "STREAM_CREATE_SIGNALING_FAILED";
break;
case bluetooth::le_audio::LeAudioHealthGroupStatType::
STREAM_CONTEXT_NOT_AVAILABLE:
os << "STREAM_CONTEXT_NOT_AVAILABLE";
break;
default:
os << "UNKNOWN";
break;
}
return os;
}
inline std::ostream& operator<<(
std::ostream& os,
const bluetooth::le_audio::LeAudioHealthDeviceStatType& stat) {
switch (stat) {
case bluetooth::le_audio::LeAudioHealthDeviceStatType::INVALID_DB:
os << "INVALID_DB";
break;
case bluetooth::le_audio::LeAudioHealthDeviceStatType::VALID_DB:
os << "VALID_DB";
break;
case bluetooth::le_audio::LeAudioHealthDeviceStatType::INVALID_CSIS:
os << "INVALID_CSIS";
break;
case bluetooth::le_audio::LeAudioHealthDeviceStatType::VALID_CSIS:
os << "VALID_CSIS";
break;
default:
os << "UNKNOWN";
break;
}
return os;
}
} // namespace bluetooth::le_audio
namespace fmt {
template <>
struct formatter
: enum_formatter {};
template <>
struct formatter
: enum_formatter {};
} // namespace fmt