1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3  * www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <base/functional/bind.h>
19 #include <base/strings/string_number_conversions.h>
20 #include <bluetooth/log.h>
21 #include <com_android_bluetooth_flags.h>
22 #include <lc3.h>
23 
24 #include <deque>
25 #include <map>
26 #include <mutex>
27 #include <optional>
28 
29 #include "audio_hal_client/audio_hal_client.h"
30 #include "audio_hal_interface/le_audio_software.h"
31 #include "bta/csis/csis_types.h"
32 #include "bta_gatt_api.h"
33 #include "bta_gatt_queue.h"
34 #include "bta_groups.h"
35 #include "bta_le_audio_api.h"
36 #include "bta_le_audio_broadcaster_api.h"
37 #include "btif/include/btif_profile_storage.h"
38 #include "btm_iso_api.h"
39 #include "client_parser.h"
40 #include "codec_interface.h"
41 #include "codec_manager.h"
42 #include "common/strings.h"
43 #include "common/time_util.h"
44 #include "content_control_id_keeper.h"
45 #include "devices.h"
46 #include "hci/controller_interface.h"
47 #include "internal_include/bt_trace.h"
48 #include "internal_include/stack_config.h"
49 #include "le_audio_health_status.h"
50 #include "le_audio_set_configuration_provider.h"
51 #include "le_audio_types.h"
52 #include "le_audio_utils.h"
53 #include "main/shim/entry.h"
54 #include "metrics_collector.h"
55 #include "os/log.h"
56 #include "osi/include/osi.h"
57 #include "osi/include/properties.h"
58 #include "stack/btm/btm_sec.h"
59 #include "stack/include/acl_api.h"
60 #include "stack/include/bt_types.h"
61 #include "stack/include/main_thread.h"
62 #include "state_machine.h"
63 #include "storage_helper.h"
64 
65 using base::Closure;
66 using bluetooth::Uuid;
67 using bluetooth::common::ToString;
68 using bluetooth::groups::DeviceGroups;
69 using bluetooth::groups::DeviceGroupsCallbacks;
70 using bluetooth::hci::IsoManager;
71 using bluetooth::hci::iso_manager::cig_create_cmpl_evt;
72 using bluetooth::hci::iso_manager::cig_remove_cmpl_evt;
73 using bluetooth::hci::iso_manager::CigCallbacks;
74 using bluetooth::le_audio::CodecManager;
75 using bluetooth::le_audio::ConnectionState;
76 using bluetooth::le_audio::ContentControlIdKeeper;
77 using bluetooth::le_audio::DeviceConnectState;
78 using bluetooth::le_audio::DsaMode;
79 using bluetooth::le_audio::DsaModes;
80 using bluetooth::le_audio::GroupNodeStatus;
81 using bluetooth::le_audio::GroupStatus;
82 using bluetooth::le_audio::GroupStreamStatus;
83 using bluetooth::le_audio::LeAudioCodecConfiguration;
84 using bluetooth::le_audio::LeAudioDevice;
85 using bluetooth::le_audio::LeAudioDeviceGroup;
86 using bluetooth::le_audio::LeAudioDeviceGroups;
87 using bluetooth::le_audio::LeAudioDevices;
88 using bluetooth::le_audio::LeAudioGroupStateMachine;
89 using bluetooth::le_audio::LeAudioHealthBasedAction;
90 using bluetooth::le_audio::LeAudioHealthDeviceStatType;
91 using bluetooth::le_audio::LeAudioHealthGroupStatType;
92 using bluetooth::le_audio::LeAudioHealthStatus;
93 using bluetooth::le_audio::LeAudioRecommendationActionCb;
94 using bluetooth::le_audio::LeAudioSinkAudioHalClient;
95 using bluetooth::le_audio::LeAudioSourceAudioHalClient;
96 using bluetooth::le_audio::UnicastMonitorModeStatus;
97 using bluetooth::le_audio::types::ase;
98 using bluetooth::le_audio::types::AseState;
99 using bluetooth::le_audio::types::AudioContexts;
100 using bluetooth::le_audio::types::AudioLocations;
101 using bluetooth::le_audio::types::BidirectionalPair;
102 using bluetooth::le_audio::types::DataPathState;
103 using bluetooth::le_audio::types::hdl_pair;
104 using bluetooth::le_audio::types::kDefaultScanDurationS;
105 using bluetooth::le_audio::types::kLeAudioContextAllBidir;
106 using bluetooth::le_audio::types::kLeAudioContextAllRemoteSinkOnly;
107 using bluetooth::le_audio::types::kLeAudioContextAllRemoteSource;
108 using bluetooth::le_audio::types::kLeAudioContextAllTypesArray;
109 using bluetooth::le_audio::types::LeAudioContextType;
110 using bluetooth::le_audio::types::PublishedAudioCapabilities;
111 using bluetooth::le_audio::utils::GetAudioContextsFromSinkMetadata;
112 using bluetooth::le_audio::utils::GetAudioContextsFromSourceMetadata;
113 
114 using namespace bluetooth;
115 
116 /* Enums */
117 enum class AudioReconfigurationResult {
118   RECONFIGURATION_NEEDED = 0x00,
119   RECONFIGURATION_NOT_NEEDED,
120   RECONFIGURATION_NOT_POSSIBLE
121 };
122 
123 enum class AudioState {
124   IDLE = 0x00,
125   READY_TO_START,
126   STARTED,
127   READY_TO_RELEASE,
128   RELEASING,
129 };
130 
operator <<(std::ostream & os,const AudioReconfigurationResult & state)131 std::ostream& operator<<(std::ostream& os,
132                          const AudioReconfigurationResult& state) {
133   switch (state) {
134     case AudioReconfigurationResult::RECONFIGURATION_NEEDED:
135       os << "RECONFIGURATION_NEEDED";
136       break;
137     case AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED:
138       os << "RECONFIGURATION_NOT_NEEDED";
139       break;
140     case AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE:
141       os << "RECONFIGRATION_NOT_POSSIBLE";
142       break;
143     default:
144       os << "UNKNOWN";
145       break;
146   }
147   return os;
148 }
149 
operator <<(std::ostream & os,const AudioState & audio_state)150 std::ostream& operator<<(std::ostream& os, const AudioState& audio_state) {
151   switch (audio_state) {
152     case AudioState::IDLE:
153       os << "IDLE";
154       break;
155     case AudioState::READY_TO_START:
156       os << "READY_TO_START";
157       break;
158     case AudioState::STARTED:
159       os << "STARTED";
160       break;
161     case AudioState::READY_TO_RELEASE:
162       os << "READY_TO_RELEASE";
163       break;
164     case AudioState::RELEASING:
165       os << "RELEASING";
166       break;
167     default:
168       os << "UNKNOWN";
169       break;
170   }
171   return os;
172 }
173 
174 namespace fmt {
175 template <>
176 struct formatter<AudioState> : ostream_formatter {};
177 }  // namespace fmt
178 
179 namespace {
180 void le_audio_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
181 
182 static void le_audio_health_status_callback(const RawAddress& addr,
183                                             int group_id,
184                                             LeAudioHealthBasedAction action);
185 
186 class LeAudioClientImpl;
187 LeAudioClientImpl* instance;
188 std::mutex instance_mutex;
189 LeAudioSourceAudioHalClient::Callbacks* audioSinkReceiver;
190 LeAudioSinkAudioHalClient::Callbacks* audioSourceReceiver;
191 CigCallbacks* stateMachineHciCallbacks;
192 LeAudioGroupStateMachine::Callbacks* stateMachineCallbacks;
193 DeviceGroupsCallbacks* device_group_callbacks;
194 LeAudioIsoDataCallback* iso_data_callback;
195 
196 /*
197  * Coordinatet Set Identification Profile (CSIP) based on CSIP 1.0
198  * and Coordinatet Set Identification Service (CSIS) 1.0
199  *
200  * CSIP allows to organize audio servers into sets e.g. Stereo Set, 5.1 Set
201  * and speed up connecting it.
202  *
203  * Since leaudio has already grouping API it was decided to integrate here CSIS
204  * and allow it to group devices semi-automatically.
205  *
206  * Flow:
207  * If connected device contains CSIS services, and it is included into CAP
208  * service, implementation marks device as a set member and waits for the
209  * bta/csis to learn about groups and notify implementation about assigned
210  * group id.
211  *
212  */
213 /* LeAudioClientImpl class represents main implementation class for le audio
214  * feature in stack. This class implements GATT, le audio and ISO related parts.
215  *
216  * This class is represented in single instance and manages a group of devices,
217  * and devices. All devices calls back static method from it and are dispatched
218  * to target receivers (e.g. ASEs, devices).
219  *
220  * This instance also implements a LeAudioClient which is a upper layer API.
221  * Also LeAudioClientCallbacks are callbacks for upper layer.
222  *
223  * This class may be bonded with Test socket which allows to drive an instance
224  * for test purposes.
225  */
226 class LeAudioClientImpl : public LeAudioClient {
227  public:
~LeAudioClientImpl()228   ~LeAudioClientImpl() {
229     alarm_free(close_vbc_timeout_);
230     alarm_free(disable_timer_);
231     alarm_free(suspend_timeout_);
232   };
233 
LeAudioClientImpl(bluetooth::le_audio::LeAudioClientCallbacks * callbacks_,LeAudioGroupStateMachine::Callbacks * state_machine_callbacks_,base::Closure initCb)234   LeAudioClientImpl(
235       bluetooth::le_audio::LeAudioClientCallbacks* callbacks_,
236       LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_,
237       base::Closure initCb)
238       : gatt_if_(0),
239         callbacks_(callbacks_),
240         active_group_id_(bluetooth::groups::kGroupUnknown),
241         configuration_context_type_(LeAudioContextType::UNINITIALIZED),
242         local_metadata_context_types_(
243             {.sink = AudioContexts(), .source = AudioContexts()}),
244         stream_setup_start_timestamp_(0),
245         stream_setup_end_timestamp_(0),
246         audio_receiver_state_(AudioState::IDLE),
247         audio_sender_state_(AudioState::IDLE),
248         in_call_(false),
249         in_voip_call_(false),
250         sink_monitor_mode_(false),
251         sink_monitor_notified_status_(std::nullopt),
252         source_monitor_mode_(false),
253         le_audio_source_hal_client_(nullptr),
254         le_audio_sink_hal_client_(nullptr),
255         close_vbc_timeout_(alarm_new("LeAudioCloseVbcTimeout")),
256         suspend_timeout_(alarm_new("LeAudioSuspendTimeout")),
257         disable_timer_(alarm_new("LeAudioDisableTimer")) {
258     LeAudioGroupStateMachine::Initialize(state_machine_callbacks_);
259     groupStateMachine_ = LeAudioGroupStateMachine::Get();
260 
261     if (bluetooth::common::InitFlags::
262             IsTargetedAnnouncementReconnectionMode()) {
263       log::info("Reconnection mode: TARGETED_ANNOUNCEMENTS");
264       reconnection_mode_ = BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS;
265     } else {
266       log::info("Reconnection mode: ALLOW_LIST");
267       reconnection_mode_ = BTM_BLE_BKG_CONNECT_ALLOW_LIST;
268     }
269 
270     if (com::android::bluetooth::flags::leaudio_enable_health_based_actions()) {
271       log::info("Loading health status module");
272       leAudioHealthStatus_ = LeAudioHealthStatus::Get();
273       leAudioHealthStatus_->RegisterCallback(
274           base::BindRepeating(le_audio_health_status_callback));
275     }
276 
277     BTA_GATTC_AppRegister(
278         le_audio_gattc_callback,
279         base::Bind(
__anonf21162180202(base::Closure initCb, uint8_t client_id, uint8_t status) 280             [](base::Closure initCb, uint8_t client_id, uint8_t status) {
281               if (status != GATT_SUCCESS) {
282                 log::error(
283                     "Can't start LeAudio profile - no gatt clients left!");
284                 return;
285               }
286               instance->gatt_if_ = client_id;
287               initCb.Run();
288             },
289             initCb),
290         true);
291 
292     DeviceGroups::Get()->Initialize(device_group_callbacks);
293   }
294 
ReconfigureAfterVbcClose()295   void ReconfigureAfterVbcClose() {
296     log::debug("VBC close timeout");
297 
298     if (IsInVoipCall()) {
299       SetInVoipCall(false);
300     }
301 
302     auto group = aseGroups_.FindById(active_group_id_);
303     if (!group) {
304       log::error("Invalid group: {}", active_group_id_);
305       return;
306     }
307 
308     /* Reconfiguration to non requiring source scenario */
309     if (sink_monitor_mode_) {
310       notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
311     }
312 
313     /* For sonification events we don't really need to reconfigure to HQ
314      * configuration, but if the previous configuration was for HQ Media,
315      * we might want to go back to that scenario.
316      */
317 
318     if ((configuration_context_type_ != LeAudioContextType::MEDIA) &&
319         (configuration_context_type_ != LeAudioContextType::GAME)) {
320       log::info(
321           "Keeping the old configuration as no HQ Media playback is needed "
322           "right now.");
323       return;
324     }
325 
326     /* Test the existing metadata against the recent availability */
327     local_metadata_context_types_.source &= group->GetAvailableContexts(
328         bluetooth::le_audio::types::kLeAudioDirectionSink);
329     if (local_metadata_context_types_.source.none()) {
330       log::warn("invalid/unknown context metadata, using 'MEDIA' instead");
331       local_metadata_context_types_.source =
332           AudioContexts(LeAudioContextType::MEDIA);
333     }
334 
335     /* Choose the right configuration context */
336     auto new_configuration_context = AdjustForVoiceAssistant(
337         group,
338         ChooseConfigurationContextType(local_metadata_context_types_.source));
339 
340     log::debug("new_configuration_context= {}",
341                ToString(new_configuration_context));
342     ReconfigureOrUpdateMetadata(group, new_configuration_context,
343                                 {.sink = local_metadata_context_types_.source,
344                                  .source = local_metadata_context_types_.sink});
345   }
346 
StartVbcCloseTimeout()347   void StartVbcCloseTimeout() {
348     if (alarm_is_scheduled(close_vbc_timeout_)) {
349       StopVbcCloseTimeout();
350     }
351 
352     static const uint64_t timeoutMs = 2000;
353     log::debug("Start VBC close timeout with {} ms",
354                static_cast<unsigned long>(timeoutMs));
355 
356     alarm_set_on_mloop(
357         close_vbc_timeout_, timeoutMs,
358         [](void*) {
359           if (instance) instance->ReconfigureAfterVbcClose();
360         },
361         nullptr);
362   }
363 
StopVbcCloseTimeout()364   void StopVbcCloseTimeout() {
365     if (alarm_is_scheduled(close_vbc_timeout_)) {
366       log::debug("Cancel VBC close timeout");
367       alarm_cancel(close_vbc_timeout_);
368     }
369   }
370 
AseInitialStateReadRequest(LeAudioDevice * leAudioDevice)371   void AseInitialStateReadRequest(LeAudioDevice* leAudioDevice) {
372     int ases_num = leAudioDevice->ases_.size();
373     void* notify_flag_ptr = NULL;
374 
375     for (int i = 0; i < ases_num; i++) {
376       /* Last read ase characteristic should issue connected state callback
377        * to upper layer
378        */
379 
380       if (leAudioDevice->notify_connected_after_read_ &&
381           (i == (ases_num - 1))) {
382         notify_flag_ptr =
383             INT_TO_PTR(leAudioDevice->notify_connected_after_read_);
384       }
385 
386       BtaGattQueue::ReadCharacteristic(leAudioDevice->conn_id_,
387                                        leAudioDevice->ases_[i].hdls.val_hdl,
388                                        OnGattReadRspStatic, notify_flag_ptr);
389     }
390   }
391 
OnGroupAddedCb(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)392   void OnGroupAddedCb(const RawAddress& address, const bluetooth::Uuid& uuid,
393                       int group_id) {
394     log::info("address: {} group uuid {} group_id: {}", address, uuid,
395               group_id);
396 
397     /* We are interested in the groups which are in the context of CAP */
398     if (uuid != bluetooth::le_audio::uuid::kCapServiceUuid) return;
399 
400     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
401     if (!leAudioDevice) return;
402     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
403       log::info("group already set: {}", leAudioDevice->group_id_);
404       return;
405     }
406 
407     group_add_node(group_id, address);
408   }
409 
410   /* If device participates in streaming the group, it has to be stopped and
411    * group needs to be reconfigured if needed to new configuration without
412    * considering this removing device.
413    */
SetDeviceAsRemovePendingAndStopGroup(LeAudioDevice * leAudioDevice)414   void SetDeviceAsRemovePendingAndStopGroup(LeAudioDevice* leAudioDevice) {
415     log::info("device {}", leAudioDevice->address_);
416     leAudioDevice->SetConnectionState(DeviceConnectState::REMOVING);
417     leAudioDevice->closing_stream_for_disconnection_ = true;
418     GroupStop(leAudioDevice->group_id_);
419   }
420 
OnGroupMemberAddedCb(const RawAddress & address,int group_id)421   void OnGroupMemberAddedCb(const RawAddress& address, int group_id) {
422     log::info("address: {} group_id: {}", address, group_id);
423 
424     auto group = aseGroups_.FindById(group_id);
425     if (!group) {
426       log::error("Not interested in group id: {}", group_id);
427       return;
428     }
429 
430     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
431     if (!leAudioDevice) return;
432     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
433       log::info("group already set: {}", leAudioDevice->group_id_);
434       return;
435     }
436 
437     if (leAudioHealthStatus_) {
438       leAudioHealthStatus_->AddStatisticForDevice(
439           leAudioDevice, LeAudioHealthDeviceStatType::VALID_CSIS);
440     }
441 
442     group_add_node(group_id, address);
443   }
444 
OnGroupMemberRemovedCb(const RawAddress & address,int group_id)445   void OnGroupMemberRemovedCb(const RawAddress& address, int group_id) {
446     log::info("address: {} group_id: {}", address, group_id);
447 
448     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
449     if (!leAudioDevice) return;
450     if (leAudioDevice->group_id_ != group_id) {
451       log::warn("Device: {} not assigned to the group.",
452                 leAudioDevice->address_);
453       return;
454     }
455 
456     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
457     if (group == NULL) {
458       log::info("device not in the group: {}, {}", leAudioDevice->address_,
459                 group_id);
460       return;
461     }
462 
463     if (leAudioHealthStatus_) {
464       leAudioHealthStatus_->RemoveStatistics(address, group->group_id_);
465     }
466 
467     if (leAudioDevice->HaveActiveAse()) {
468       SetDeviceAsRemovePendingAndStopGroup(leAudioDevice);
469       return;
470     }
471 
472     group_remove_node(group, address);
473   }
474 
475   /* This callback happens if kLeAudioDeviceSetStateTimeoutMs timeout happens
476    * during transition from origin to target state
477    */
OnLeAudioDeviceSetStateTimeout(int group_id)478   void OnLeAudioDeviceSetStateTimeout(int group_id) {
479     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
480 
481     if (!group) {
482       /* Group removed */
483       return;
484     }
485 
486     bool check_if_recovery_needed =
487         group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
488 
489     if (leAudioHealthStatus_) {
490       leAudioHealthStatus_->AddStatisticForGroup(
491           group, LeAudioHealthGroupStatType::STREAM_CREATE_SIGNALING_FAILED);
492     }
493 
494     log::error(
495         "State not achieved on time for group: group id {}, current state {}, "
496         "target state: {}, check_if_recovery_needed: {}",
497         group_id, ToString(group->GetState()),
498         ToString(group->GetTargetState()), check_if_recovery_needed);
499     group->SetTargetState(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
500     group->ClearAllCises();
501     group->PrintDebugState();
502 
503     /* There is an issue with a setting up stream or any other operation which
504      * are gatt operations. It means peer is not responsable. Lets close ACL
505      */
506     CancelStreamingRequest();
507     LeAudioDevice* leAudioDevice = group->GetFirstActiveDevice();
508     if (leAudioDevice == nullptr) {
509       log::error("Shouldn't be called without an active device.");
510       leAudioDevice = group->GetFirstDevice();
511       if (leAudioDevice == nullptr) {
512         log::error("Front device is null. Number of devices: {}",
513                    group->Size());
514         return;
515       }
516     }
517 
518     /* If Timeout happens on stream close and stream is closing just for the
519      * purpose of device disconnection, do not bother with recovery mode
520      */
521     bool recovery = true;
522     if (check_if_recovery_needed) {
523       for (auto tmpDevice = leAudioDevice; tmpDevice != nullptr;
524            tmpDevice = group->GetNextActiveDevice(tmpDevice)) {
525         if (tmpDevice->closing_stream_for_disconnection_) {
526           recovery = false;
527           break;
528         }
529       }
530     }
531 
532     do {
533       DisconnectDevice(leAudioDevice, true, recovery);
534       leAudioDevice = group->GetNextActiveDevice(leAudioDevice);
535     } while (leAudioDevice);
536 
537     if (recovery) {
538       /* Both devices will  be disconnected soon. Notify upper layer that group
539        * is inactive */
540       groupSetAndNotifyInactive();
541     }
542   }
543 
OnDeviceAutonomousStateTransitionTimeout(LeAudioDevice * leAudioDevice)544   void OnDeviceAutonomousStateTransitionTimeout(LeAudioDevice* leAudioDevice) {
545     log::error("Device {}, failed to complete autonomous transition",
546                leAudioDevice->address_);
547     DisconnectDevice(leAudioDevice, true);
548   }
549 
UpdateLocationsAndContextsAvailability(LeAudioDeviceGroup * group,bool force=false)550   void UpdateLocationsAndContextsAvailability(LeAudioDeviceGroup* group,
551                                               bool force = false) {
552     bool group_conf_changed = group->ReloadAudioLocations();
553     group_conf_changed |= group->ReloadAudioDirections();
554     group_conf_changed |= group->UpdateAudioContextAvailability();
555     if (group_conf_changed || force) {
556       /* All the configurations should be recalculated for the new conditions */
557       group->InvalidateCachedConfigurations();
558       group->InvalidateGroupStrategy();
559       callbacks_->OnAudioConf(group->audio_directions_, group->group_id_,
560                               group->snk_audio_locations_.to_ulong(),
561                               group->src_audio_locations_.to_ulong(),
562                               group->GetAvailableContexts().value());
563     }
564   }
565 
SuspendedForReconfiguration()566   void SuspendedForReconfiguration() {
567     if (audio_sender_state_ > AudioState::IDLE) {
568       LeAudioLogHistory::Get()->AddLogHistory(
569           kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
570           kLogAfSuspendForReconfig + "LocalSource",
571           "r_state: " + ToString(audio_receiver_state_) +
572               "s_state: " + ToString(audio_sender_state_));
573       le_audio_source_hal_client_->SuspendedForReconfiguration();
574     }
575     if (audio_receiver_state_ > AudioState::IDLE) {
576       LeAudioLogHistory::Get()->AddLogHistory(
577           kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
578           kLogAfSuspendForReconfig + "LocalSink",
579           "r_state: " + ToString(audio_receiver_state_) +
580               "s_state: " + ToString(audio_sender_state_));
581       le_audio_sink_hal_client_->SuspendedForReconfiguration();
582     }
583   }
584 
ReconfigurationComplete(uint8_t directions)585   void ReconfigurationComplete(uint8_t directions) {
586     if (directions & bluetooth::le_audio::types::kLeAudioDirectionSink) {
587       LeAudioLogHistory::Get()->AddLogHistory(
588           kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
589           kLogAfReconfigComplete + "LocalSource",
590           "r_state: " + ToString(audio_receiver_state_) +
591               "s_state: " + ToString(audio_sender_state_));
592 
593       le_audio_source_hal_client_->ReconfigurationComplete();
594     }
595     if (directions & bluetooth::le_audio::types::kLeAudioDirectionSource) {
596       LeAudioLogHistory::Get()->AddLogHistory(
597           kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
598           kLogAfReconfigComplete + "LocalSink",
599           "r_state: " + ToString(audio_receiver_state_) +
600               "s_state: " + ToString(audio_sender_state_));
601 
602       le_audio_sink_hal_client_->ReconfigurationComplete();
603     }
604   }
605 
CancelLocalAudioSourceStreamingRequest()606   void CancelLocalAudioSourceStreamingRequest() {
607     le_audio_source_hal_client_->CancelStreamingRequest();
608 
609     LeAudioLogHistory::Get()->AddLogHistory(
610         kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
611         kLogAfCancel + "LocalSource",
612         "s_state: " + ToString(audio_sender_state_));
613 
614     audio_sender_state_ = AudioState::IDLE;
615   }
616 
CancelLocalAudioSinkStreamingRequest()617   void CancelLocalAudioSinkStreamingRequest() {
618     le_audio_sink_hal_client_->CancelStreamingRequest();
619 
620     LeAudioLogHistory::Get()->AddLogHistory(
621         kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
622         kLogAfCancel + "LocalSink",
623         "s_state: " + ToString(audio_receiver_state_));
624 
625     audio_receiver_state_ = AudioState::IDLE;
626   }
627 
CancelStreamingRequest()628   void CancelStreamingRequest() {
629     if (audio_sender_state_ >= AudioState::READY_TO_START) {
630       CancelLocalAudioSourceStreamingRequest();
631     }
632 
633     if (audio_receiver_state_ >= AudioState::READY_TO_START) {
634       CancelLocalAudioSinkStreamingRequest();
635     }
636   }
637 
group_add_node(const int group_id,const RawAddress & address,bool update_group_module=false)638   void group_add_node(const int group_id, const RawAddress& address,
639                       bool update_group_module = false) {
640     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
641     LeAudioDeviceGroup* new_group;
642     LeAudioDeviceGroup* old_group = nullptr;
643 
644     if (!leAudioDevice) {
645       /* TODO This part possible to remove as this is to handle adding device to
646        * the group which is unknown and not connected.
647        */
648       log::info("leAudioDevice unknown , address: {} group: 0x{:x}", address,
649                 group_id);
650 
651       if (group_id == bluetooth::groups::kGroupUnknown) return;
652 
653       log::info("Set member adding ...");
654       leAudioDevices_.Add(address, DeviceConnectState::CONNECTING_BY_USER);
655       leAudioDevice = leAudioDevices_.FindByAddress(address);
656     } else {
657       if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
658         old_group = aseGroups_.FindById(leAudioDevice->group_id_);
659       }
660     }
661 
662     auto id = DeviceGroups::Get()->GetGroupId(
663         address, bluetooth::le_audio::uuid::kCapServiceUuid);
664     if (group_id == bluetooth::groups::kGroupUnknown) {
665       if (id == bluetooth::groups::kGroupUnknown) {
666         DeviceGroups::Get()->AddDevice(
667             address, bluetooth::le_audio::uuid::kCapServiceUuid);
668         /* We will get back here when group will be created */
669         return;
670       }
671 
672       new_group = aseGroups_.Add(id);
673       if (!new_group) {
674         log::error("can't create group - group is already there?");
675         return;
676       }
677     } else {
678       log::assert_that(id == group_id,
679                        "group id missmatch? leaudio id: {}, groups module {}",
680                        group_id, id);
681       new_group = aseGroups_.FindById(group_id);
682       if (!new_group) {
683         new_group = aseGroups_.Add(group_id);
684       } else {
685         if (new_group->IsDeviceInTheGroup(leAudioDevice)) return;
686       }
687     }
688 
689     log::debug("New group {}, id: {}", fmt::ptr(new_group),
690                new_group->group_id_);
691 
692     /* If device was in the group and it was not removed by the application,
693      * lets do it now
694      */
695     if (old_group) group_remove_node(old_group, address, update_group_module);
696 
697     new_group->AddNode(leAudioDevices_.GetByAddress(address));
698 
699     callbacks_->OnGroupNodeStatus(address, new_group->group_id_,
700                                   GroupNodeStatus::ADDED);
701 
702     /* If device is connected and added to the group, lets read ASE states */
703     if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID)
704       AseInitialStateReadRequest(leAudioDevice);
705 
706     if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTED) {
707       UpdateLocationsAndContextsAvailability(new_group);
708     }
709   }
710 
GroupAddNode(const int group_id,const RawAddress & address)711   void GroupAddNode(const int group_id, const RawAddress& address) override {
712     auto id = DeviceGroups::Get()->GetGroupId(
713         address, bluetooth::le_audio::uuid::kCapServiceUuid);
714     if (id == group_id) return;
715 
716     if (id != bluetooth::groups::kGroupUnknown) {
717       DeviceGroups::Get()->RemoveDevice(address, id);
718     }
719 
720     DeviceGroups::Get()->AddDevice(
721         address, bluetooth::le_audio::uuid::kCapServiceUuid, group_id);
722   }
723 
remove_group_if_possible(LeAudioDeviceGroup * group)724   void remove_group_if_possible(LeAudioDeviceGroup* group) {
725     if (!group) {
726       log::debug("group is null");
727       return;
728     }
729     log::debug("Group {}, id: {}, size: {}, is cig_state {}", fmt::ptr(group),
730                group->group_id_, group->Size(),
731                ToString(group->cig.GetState()));
732     if (group->IsEmpty() &&
733         (group->cig.GetState() == bluetooth::le_audio::types::CigState::NONE)) {
734       lastNotifiedGroupStreamStatusMap_.erase(group->group_id_);
735       aseGroups_.Remove(group->group_id_);
736     }
737   }
738 
group_remove_node(LeAudioDeviceGroup * group,const RawAddress & address,bool update_group_module=false)739   void group_remove_node(LeAudioDeviceGroup* group, const RawAddress& address,
740                          bool update_group_module = false) {
741     int group_id = group->group_id_;
742     group->RemoveNode(leAudioDevices_.GetByAddress(address));
743 
744     if (update_group_module) {
745       int groups_group_id = DeviceGroups::Get()->GetGroupId(
746           address, bluetooth::le_audio::uuid::kCapServiceUuid);
747       if (groups_group_id == group_id) {
748         DeviceGroups::Get()->RemoveDevice(address, group_id);
749       }
750     }
751 
752     callbacks_->OnGroupNodeStatus(address, group_id, GroupNodeStatus::REMOVED);
753 
754     /* Remove group if this was the last leAudioDevice in this group */
755     if (group->IsEmpty()) {
756       remove_group_if_possible(group);
757       return;
758     }
759 
760     /* Removing node from group requires updating group context availability */
761     UpdateLocationsAndContextsAvailability(group);
762   }
763 
GroupRemoveNode(const int group_id,const RawAddress & address)764   void GroupRemoveNode(const int group_id, const RawAddress& address) override {
765     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
766     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
767 
768     log::info("group_id: {} address: {}", group_id, address);
769 
770     if (!leAudioDevice) {
771       log::error("Skipping unknown leAudioDevice, address: {}", address);
772       return;
773     }
774 
775     if (leAudioDevice->group_id_ != group_id) {
776       log::error("Device is not in group_id: {}, but in group_id: {}", group_id,
777                  leAudioDevice->group_id_);
778       return;
779     }
780 
781     if (group == NULL) {
782       log::error("device not in the group ?!");
783       return;
784     }
785 
786     if (leAudioDevice->HaveActiveAse()) {
787       SetDeviceAsRemovePendingAndStopGroup(leAudioDevice);
788       return;
789     }
790 
791     group_remove_node(group, address, true);
792   }
793 
ChooseMetadataContextType(AudioContexts metadata_context_type)794   AudioContexts ChooseMetadataContextType(AudioContexts metadata_context_type) {
795     /* This function takes already filtered contexts which we are plannig to use
796      * in the Enable or UpdateMetadata command.
797      * Note we are not changing stream configuration here, but just the list of
798      * the contexts in the Metadata which will be provide to remote side.
799      * Ideally, we should send all the bits we have, but not all headsets like
800      * it.
801      */
802     if (osi_property_get_bool(kAllowMultipleContextsInMetadata, true)) {
803       return metadata_context_type;
804     }
805 
806     log::debug("Converting to single context type: {}",
807                metadata_context_type.to_string());
808 
809     /* Mini policy */
810     if (metadata_context_type.any()) {
811       LeAudioContextType context_priority_list[] = {
812           /* Highest priority first */
813           LeAudioContextType::CONVERSATIONAL,
814           LeAudioContextType::RINGTONE,
815           LeAudioContextType::LIVE,
816           LeAudioContextType::VOICEASSISTANTS,
817           LeAudioContextType::GAME,
818           LeAudioContextType::MEDIA,
819           LeAudioContextType::EMERGENCYALARM,
820           LeAudioContextType::ALERTS,
821           LeAudioContextType::INSTRUCTIONAL,
822           LeAudioContextType::NOTIFICATIONS,
823           LeAudioContextType::SOUNDEFFECTS,
824       };
825       for (auto ct : context_priority_list) {
826         if (metadata_context_type.test(ct)) {
827           log::debug("Converted to single context type: {}", ToString(ct));
828           return AudioContexts(ct);
829         }
830       }
831     }
832 
833     /* Fallback to BAP mandated context type */
834     log::warn("Invalid/unknown context, using 'UNSPECIFIED'");
835     return AudioContexts(LeAudioContextType::UNSPECIFIED);
836   }
837 
838   /* Return true if stream is started */
GroupStream(int group_id,LeAudioContextType configuration_context_type,BidirectionalPair<AudioContexts> remote_contexts)839   bool GroupStream(int group_id, LeAudioContextType configuration_context_type,
840                    BidirectionalPair<AudioContexts> remote_contexts) {
841     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
842 
843     log::debug("configuration_context_type= {}",
844                ToString(configuration_context_type));
845 
846     log::debug("");
847     if (configuration_context_type >= LeAudioContextType::RFU) {
848       log::error("stream context type is not supported: {}",
849                  ToHexString(configuration_context_type));
850       return false;
851     }
852 
853     if (!group) {
854       log::error("unknown group id: {}", group_id);
855       return false;
856     }
857 
858     log::debug("group state={}, target_state={}", ToString(group->GetState()),
859                ToString(group->GetTargetState()));
860 
861     if (!group->IsAnyDeviceConnected()) {
862       log::error("group {} is not connected", group_id);
863       return false;
864     }
865 
866     /* Check if any group is in the transition state. If so, we don't allow to
867      * start new group to stream
868      */
869     if (group->IsInTransition()) {
870       /* WARNING: Due to group state machine limitations, we should not
871        * interrupt any ongoing transition. We will check if another
872        * reconfiguration is needed once the group reaches streaming state.
873        */
874       log::warn(
875           "Group is already in the transition state. Waiting for the target "
876           "state to be reached.");
877       return false;
878     }
879 
880     /* Make sure we do not take the local sink metadata when only the local
881      * source scenario is about to be started (e.g. MEDIA).
882      */
883     if (!kLeAudioContextAllBidir.test(configuration_context_type)) {
884       remote_contexts.source.clear();
885     }
886 
887     /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */
888     auto ccid_contexts = remote_contexts;
889     if (IsInVoipCall() && !IsInCall()) {
890       ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL);
891       ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL);
892     }
893 
894     BidirectionalPair<std::vector<uint8_t>> ccids = {
895         .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids(
896             ccid_contexts.sink),
897         .source = ContentControlIdKeeper::GetInstance()->GetAllCcids(
898             ccid_contexts.source)};
899     if (group->IsPendingConfiguration()) {
900       return groupStateMachine_->ConfigureStream(
901           group, configuration_context_type_, remote_contexts, ccids);
902     } else if (group->GetState() !=
903                AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
904       stream_setup_start_timestamp_ =
905           bluetooth::common::time_get_os_boottime_us();
906     }
907 
908     /* If assistant have some connected delegators that needs to be informed
909      * when there would be request to stream unicast.
910      */
911     if (com::android::bluetooth::flags::
912             leaudio_broadcast_audio_handover_policies() &&
913         !sink_monitor_mode_ && source_monitor_mode_ && !group->IsStreaming()) {
914       callbacks_->OnUnicastMonitorModeStatus(
915           bluetooth::le_audio::types::kLeAudioDirectionSource,
916           UnicastMonitorModeStatus::STREAMING_REQUESTED);
917     }
918 
919     bool result = groupStateMachine_->StartStream(
920         group, configuration_context_type, remote_contexts, ccids);
921 
922     return result;
923   }
924 
GroupStream(const int group_id,uint16_t context_type)925   void GroupStream(const int group_id, uint16_t context_type) override {
926     BidirectionalPair<AudioContexts> initial_contexts = {
927         AudioContexts(context_type), AudioContexts(context_type)};
928     GroupStream(group_id, LeAudioContextType(context_type), initial_contexts);
929   }
930 
GroupSuspend(const int group_id)931   void GroupSuspend(const int group_id) override {
932     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
933 
934     if (!group) {
935       log::error("unknown group id: {}", group_id);
936       return;
937     }
938 
939     if (!group->IsAnyDeviceConnected()) {
940       log::error("group is not connected");
941       return;
942     }
943 
944     if (group->IsInTransition()) {
945       log::info(", group is in transition from: {} to: {}",
946                 ToString(group->GetState()), ToString(group->GetTargetState()));
947       return;
948     }
949 
950     if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
951       log::error(", invalid current state of group: {}",
952                  ToString(group->GetState()));
953       return;
954     }
955 
956     groupStateMachine_->SuspendStream(group);
957   }
958 
GroupStop(const int group_id)959   void GroupStop(const int group_id) override {
960     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
961 
962     if (!group) {
963       log::error("unknown group id: {}", group_id);
964       return;
965     }
966 
967     if (group->IsEmpty()) {
968       log::error("group is empty");
969       return;
970     }
971 
972     if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {
973       if (group->GetTargetState() != AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {
974         log::warn("group {} was about to stream, but got canceled: {}",
975                   group_id, ToString(group->GetTargetState()));
976         group->SetTargetState(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
977       } else {
978         log::warn(", group {} already stopped: {}", group_id,
979                   ToString(group->GetState()));
980       }
981       return;
982     }
983 
984     groupStateMachine_->StopStream(group);
985   }
986 
GroupDestroy(const int group_id)987   void GroupDestroy(const int group_id) override {
988     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
989 
990     if (!group) {
991       log::error("unknown group id: {}", group_id);
992       return;
993     }
994 
995     // Disconnect and remove each device within the group
996     auto* dev = group->GetFirstDevice();
997     while (dev) {
998       auto* next_dev = group->GetNextDevice(dev);
999       RemoveDevice(dev->address_);
1000       dev = next_dev;
1001     }
1002   }
1003 
SetCodecConfigPreference(int group_id,bluetooth::le_audio::btle_audio_codec_config_t input_codec_config,bluetooth::le_audio::btle_audio_codec_config_t output_codec_config)1004   void SetCodecConfigPreference(
1005       int group_id,
1006       bluetooth::le_audio::btle_audio_codec_config_t input_codec_config,
1007       bluetooth::le_audio::btle_audio_codec_config_t output_codec_config)
1008       override {
1009     // TODO Implement
1010   }
1011 
SetCcidInformation(int ccid,int context_type)1012   void SetCcidInformation(int ccid, int context_type) override {
1013     log::debug("Ccid: {}, context type {}", ccid, context_type);
1014 
1015     ContentControlIdKeeper::GetInstance()->SetCcid(AudioContexts(context_type),
1016                                                    ccid);
1017   }
1018 
SetInCall(bool in_call)1019   void SetInCall(bool in_call) override {
1020     log::debug("in_call: {}", in_call);
1021     in_call_ = in_call;
1022   }
1023 
IsInCall()1024   bool IsInCall() override { return in_call_; }
1025 
SetInVoipCall(bool in_call)1026   void SetInVoipCall(bool in_call) override {
1027     log::debug("in_voip_call: {}", in_call);
1028     in_voip_call_ = in_call;
1029   }
1030 
IsInVoipCall()1031   bool IsInVoipCall() override { return in_voip_call_; }
1032 
IsInStreaming()1033   bool IsInStreaming() override {
1034     return audio_sender_state_ == AudioState::STARTED ||
1035            audio_receiver_state_ == AudioState::STARTED;
1036   }
1037 
SetUnicastMonitorMode(uint8_t direction,bool enable)1038   void SetUnicastMonitorMode(uint8_t direction, bool enable) override {
1039     if (!com::android::bluetooth::flags::
1040             leaudio_broadcast_audio_handover_policies()) {
1041       log::warn(
1042           "Monitor mode is disabled, Set Unicast Monitor mode is ignored");
1043       return;
1044     }
1045 
1046     if (direction == bluetooth::le_audio::types::kLeAudioDirectionSink) {
1047       /* Cleanup Sink HAL client interface if listening mode is toggled off
1048        * before group activation (active group context would take care of
1049        * Sink HAL client cleanup).
1050        */
1051       if (sink_monitor_mode_ && !enable && le_audio_sink_hal_client_ &&
1052           active_group_id_ == bluetooth::groups::kGroupUnknown) {
1053         local_metadata_context_types_.sink.clear();
1054         le_audio_sink_hal_client_->Stop();
1055         le_audio_sink_hal_client_.reset();
1056       }
1057 
1058       log::debug("enable: {}", enable);
1059       sink_monitor_mode_ = enable;
1060     } else if (direction ==
1061                bluetooth::le_audio::types::kLeAudioDirectionSource) {
1062       log::debug("enable: {}", enable);
1063       source_monitor_mode_ = enable;
1064 
1065       if (!enable) {
1066         return;
1067       }
1068 
1069       LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1070       if (!group) {
1071         callbacks_->OnUnicastMonitorModeStatus(
1072             bluetooth::le_audio::types::kLeAudioDirectionSource,
1073             UnicastMonitorModeStatus::STREAMING_SUSPENDED);
1074 
1075         return;
1076       }
1077 
1078       if (group->IsStreaming()) {
1079         callbacks_->OnUnicastMonitorModeStatus(
1080             bluetooth::le_audio::types::kLeAudioDirectionSource,
1081             UnicastMonitorModeStatus::STREAMING);
1082       } else {
1083         callbacks_->OnUnicastMonitorModeStatus(
1084             bluetooth::le_audio::types::kLeAudioDirectionSource,
1085             UnicastMonitorModeStatus::STREAMING_SUSPENDED);
1086       }
1087     } else {
1088       log::error("invalid direction: 0x{:02x} monitor mode set", direction);
1089     }
1090   }
1091 
SendAudioProfilePreferences(const int group_id,bool is_output_preference_le_audio,bool is_duplex_preference_le_audio)1092   void SendAudioProfilePreferences(
1093       const int group_id, bool is_output_preference_le_audio,
1094       bool is_duplex_preference_le_audio) override {
1095     log::info(
1096         "group_id: {}, is_output_preference_le_audio: {}, "
1097         "is_duplex_preference_le_audio: {}",
1098         group_id, is_output_preference_le_audio, is_duplex_preference_le_audio);
1099     if (group_id == bluetooth::groups::kGroupUnknown) {
1100       log::warn("Unknown group_id");
1101       return;
1102     }
1103     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1104     if (!group) {
1105       log::warn("group_id {} does not exist", group_id);
1106       return;
1107     }
1108 
1109     group->is_output_preference_le_audio = is_output_preference_le_audio;
1110     group->is_duplex_preference_le_audio = is_duplex_preference_le_audio;
1111   }
1112 
SetGroupAllowedContextMask(int group_id,int sink_context_types,int source_context_types)1113   void SetGroupAllowedContextMask(int group_id, int sink_context_types,
1114                                   int source_context_types) override {
1115     log::info("group_id: {}, sink context types: {}, source context types: {}",
1116               group_id, sink_context_types, source_context_types);
1117 
1118     if (group_id == bluetooth::groups::kGroupUnknown) {
1119       log::warn("Unknown group_id");
1120       return;
1121     }
1122     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1123     if (!group) {
1124       log::warn("group_id {} does not exist", group_id);
1125       return;
1126     }
1127 
1128     BidirectionalPair<AudioContexts> allowed_contexts = {
1129         .sink = AudioContexts(sink_context_types),
1130         .source = AudioContexts(source_context_types),
1131     };
1132 
1133     group->SetAllowedContextMask(allowed_contexts);
1134   }
1135 
StartAudioSession(LeAudioDeviceGroup * group)1136   void StartAudioSession(LeAudioDeviceGroup* group) {
1137     /* This function is called when group is not yet set to active.
1138      * This is why we don't have to check if session is started already.
1139      * Just check if it is acquired.
1140      */
1141     log::assert_that(active_group_id_ == bluetooth::groups::kGroupUnknown,
1142                      "Active group is not set.");
1143     log::assert_that(le_audio_source_hal_client_ != nullptr,
1144                      "Source session not acquired");
1145     log::assert_that(le_audio_sink_hal_client_ != nullptr,
1146                      "Sink session not acquired");
1147 
1148     DsaModes dsa_modes = {DsaMode::DISABLED};
1149     if (com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
1150       dsa_modes = group->GetAllowedDsaModes();
1151     }
1152 
1153     /* We assume that peer device always use same frame duration */
1154     uint32_t frame_duration_us = 0;
1155     if (!current_encoder_config_.IsInvalid()) {
1156       frame_duration_us = current_encoder_config_.data_interval_us;
1157     } else if (!current_decoder_config_.IsInvalid()) {
1158       frame_duration_us = current_decoder_config_.data_interval_us;
1159     } else {
1160       log::assert_that(true, "Both configs are invalid");
1161     }
1162 
1163     L2CA_SetEcosystemBaseInterval(frame_duration_us / 1250);
1164 
1165     audio_framework_source_config.data_interval_us = frame_duration_us;
1166     le_audio_source_hal_client_->Start(audio_framework_source_config,
1167                                        audioSinkReceiver, dsa_modes);
1168 
1169     /* We use same frame duration for sink/source */
1170     audio_framework_sink_config.data_interval_us = frame_duration_us;
1171 
1172     /* If group supports more than 16kHz for the microphone in converstional
1173      * case let's use that also for Audio Framework.
1174      */
1175     auto sink_configuration = group->GetAudioSessionCodecConfigForDirection(
1176         LeAudioContextType::CONVERSATIONAL,
1177         bluetooth::le_audio::types::kLeAudioDirectionSource);
1178     if (!sink_configuration.IsInvalid() &&
1179         sink_configuration.sample_rate >
1180             bluetooth::audio::le_audio::kSampleRate16000) {
1181       audio_framework_sink_config.sample_rate = sink_configuration.sample_rate;
1182     }
1183 
1184     le_audio_sink_hal_client_->Start(audio_framework_sink_config,
1185                                      audioSourceReceiver, dsa_modes);
1186   }
1187 
isOutputPreferenceLeAudio(const RawAddress & address)1188   bool isOutputPreferenceLeAudio(const RawAddress& address) {
1189     log::info("address: {}, active_group_id_: {}", address.ToStringForLogging(),
1190               active_group_id_);
1191     std::vector<RawAddress> active_leaudio_devices =
1192         GetGroupDevices(active_group_id_);
1193     if (std::find(active_leaudio_devices.begin(), active_leaudio_devices.end(),
1194                   address) == active_leaudio_devices.end()) {
1195       log::info("Device {} is not active for LE Audio",
1196                 address.ToStringForLogging());
1197       return false;
1198     }
1199 
1200     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1201     log::info("active_group_id: {}, is_output_preference_le_audio_: {}",
1202               group->group_id_, group->is_output_preference_le_audio);
1203     return group->is_output_preference_le_audio;
1204   }
1205 
isDuplexPreferenceLeAudio(const RawAddress & address)1206   bool isDuplexPreferenceLeAudio(const RawAddress& address) {
1207     log::info("address: {}, active_group_id_: {}", address.ToStringForLogging(),
1208               active_group_id_);
1209     std::vector<RawAddress> active_leaudio_devices =
1210         GetGroupDevices(active_group_id_);
1211     if (std::find(active_leaudio_devices.begin(), active_leaudio_devices.end(),
1212                   address) == active_leaudio_devices.end()) {
1213       log::info("Device {} is not active for LE Audio",
1214                 address.ToStringForLogging());
1215       return false;
1216     }
1217 
1218     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1219     log::info("active_group_id: {}, is_duplex_preference_le_audio: {}",
1220               group->group_id_, group->is_duplex_preference_le_audio);
1221     return group->is_duplex_preference_le_audio;
1222   }
1223 
groupSetAndNotifyInactive(void)1224   void groupSetAndNotifyInactive(void) {
1225     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
1226       return;
1227     }
1228     sink_monitor_notified_status_ = std::nullopt;
1229     log::info("Group id: {}", active_group_id_);
1230 
1231     if (alarm_is_scheduled(suspend_timeout_)) alarm_cancel(suspend_timeout_);
1232 
1233     StopAudio();
1234     ClientAudioInterfaceRelease();
1235 
1236     callbacks_->OnGroupStatus(active_group_id_, GroupStatus::INACTIVE);
1237     active_group_id_ = bluetooth::groups::kGroupUnknown;
1238   }
1239 
GroupSetActive(const int group_id)1240   void GroupSetActive(const int group_id) override {
1241     log::info("group_id: {}", group_id);
1242 
1243     if (group_id == bluetooth::groups::kGroupUnknown) {
1244       if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
1245         callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1246         /* Nothing to do */
1247         return;
1248       }
1249 
1250       log::info("Active group_id changed {} -> {}", active_group_id_, group_id);
1251       auto group_id_to_close = active_group_id_;
1252       groupSetAndNotifyInactive();
1253       GroupStop(group_id_to_close);
1254 
1255       return;
1256     }
1257 
1258     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1259     if (!group) {
1260       log::error("Invalid group: {}", static_cast<int>(group_id));
1261       callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1262       return;
1263     }
1264 
1265     if (group->NumOfConnected() == 0) {
1266       log::error("Group: {} is not connected anymore",
1267                  static_cast<int>(group_id));
1268       callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1269       return;
1270     }
1271 
1272     if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
1273       if (active_group_id_ == group_id) {
1274         log::info("Group is already active: {}",
1275                   static_cast<int>(active_group_id_));
1276         callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
1277         return;
1278       }
1279       log::info("switching active group to: {}", group_id);
1280 
1281       auto result =
1282           CodecManager::GetInstance()->UpdateActiveUnicastAudioHalClient(
1283               le_audio_source_hal_client_.get(),
1284               le_audio_sink_hal_client_.get(), false);
1285       log::assert_that(result, "Could not update session to codec manager");
1286     }
1287 
1288     if (!le_audio_source_hal_client_) {
1289       le_audio_source_hal_client_ =
1290           LeAudioSourceAudioHalClient::AcquireUnicast();
1291       if (!le_audio_source_hal_client_) {
1292         log::error("could not acquire audio source interface");
1293         callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1294         return;
1295       }
1296     }
1297 
1298     if (!le_audio_sink_hal_client_) {
1299       le_audio_sink_hal_client_ = LeAudioSinkAudioHalClient::AcquireUnicast();
1300       if (!le_audio_sink_hal_client_) {
1301         log::error("could not acquire audio sink interface");
1302         callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1303         return;
1304       }
1305     }
1306 
1307     auto result =
1308         CodecManager::GetInstance()->UpdateActiveUnicastAudioHalClient(
1309             le_audio_source_hal_client_.get(), le_audio_sink_hal_client_.get(),
1310             true);
1311     log::assert_that(result, "Could not update session to codec manager");
1312 
1313     /* Mini policy: Try configure audio HAL sessions with most recent context.
1314      * If reconfiguration is not needed it means, context type is not supported.
1315      * If most recent scenario is not supported, try to find first supported.
1316      */
1317     LeAudioContextType default_context_type = configuration_context_type_;
1318     if (!group->IsAudioSetConfigurationAvailable(default_context_type)) {
1319       if (group->IsAudioSetConfigurationAvailable(
1320               LeAudioContextType::UNSPECIFIED)) {
1321         default_context_type = LeAudioContextType::UNSPECIFIED;
1322         default_context_type = LeAudioContextType::UNSPECIFIED;
1323       } else {
1324         for (LeAudioContextType context_type : kLeAudioContextAllTypesArray) {
1325           if (group->IsAudioSetConfigurationAvailable(context_type)) {
1326             default_context_type = context_type;
1327             break;
1328           }
1329         }
1330       }
1331     }
1332 
1333     /* Only update the configuration audio context and audio coding session
1334      * parameters if needed.
1335      */
1336     UpdateConfigAndCheckIfReconfigurationIsNeeded(group, default_context_type);
1337 
1338     auto previous_active_group = active_group_id_;
1339     log::info("Active group_id changed {} -> {}", previous_active_group,
1340               group_id);
1341 
1342     if (previous_active_group == bluetooth::groups::kGroupUnknown) {
1343       /* Expose audio sessions if there was no previous active group */
1344       StartAudioSession(group);
1345       active_group_id_ = group_id;
1346     } else {
1347       /* In case there was an active group. Stop the stream, but before that, set
1348        * the new group so the group change is correctly handled in OnStateMachineStatusReportCb
1349        */
1350       active_group_id_ = group_id;
1351       GroupStop(previous_active_group);
1352       callbacks_->OnGroupStatus(previous_active_group, GroupStatus::INACTIVE);
1353     }
1354 
1355     /* Reset sink listener notified status */
1356     sink_monitor_notified_status_ = std::nullopt;
1357     if (com::android::bluetooth::flags::
1358             leaudio_codec_config_callback_order_fix()) {
1359       SendAudioGroupSelectableCodecConfigChanged(group);
1360       SendAudioGroupCurrentCodecConfigChanged(group);
1361       callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
1362     } else {
1363       callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
1364       SendAudioGroupSelectableCodecConfigChanged(group);
1365     }
1366   }
1367 
SetEnableState(const RawAddress & address,bool enabled)1368   void SetEnableState(const RawAddress& address, bool enabled) override {
1369     log::info("{}: {}", address, enabled ? "enabled" : "disabled");
1370     auto leAudioDevice = leAudioDevices_.FindByAddress(address);
1371     if (leAudioDevice == nullptr) {
1372       log::warn("{} is null", address);
1373       return;
1374     }
1375 
1376     auto group_id = leAudioDevice->group_id_;
1377     auto group = aseGroups_.FindById(group_id);
1378     if (group == nullptr) {
1379       log::warn("Group {} is not available", group_id);
1380       return;
1381     }
1382 
1383     if (enabled) {
1384       group->Enable(gatt_if_, reconnection_mode_);
1385     } else {
1386       group->Disable(gatt_if_);
1387     }
1388   }
1389 
RemoveDevice(const RawAddress & address)1390   void RemoveDevice(const RawAddress& address) override {
1391     log::info(": {}", address);
1392     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1393     if (!leAudioDevice) {
1394       return;
1395     }
1396 
1397     /* Remove device from the background connect if it is there */
1398     BTA_GATTC_CancelOpen(gatt_if_, address, false);
1399     btif_storage_set_leaudio_autoconnect(address, false);
1400 
1401     log::info("{}, state: {}", address,
1402               bluetooth::common::ToString(leAudioDevice->GetConnectionState()));
1403     auto connection_state = leAudioDevice->GetConnectionState();
1404     switch (connection_state) {
1405       case DeviceConnectState::REMOVING:
1406         /* Just return, and let device disconnect */
1407         return;
1408       case DeviceConnectState::CONNECTED:
1409       case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY:
1410       case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY:
1411         /* ACL exist in this case, disconnect and mark as removing */
1412         Disconnect(address);
1413         [[fallthrough]];
1414       case DeviceConnectState::DISCONNECTING:
1415       case DeviceConnectState::DISCONNECTING_AND_RECOVER:
1416         /* Device is disconnecting, just mark it shall be removed after all. */
1417         leAudioDevice->SetConnectionState(DeviceConnectState::REMOVING);
1418         return;
1419       case DeviceConnectState::CONNECTING_BY_USER:
1420         BTA_GATTC_CancelOpen(gatt_if_, address, true);
1421         [[fallthrough]];
1422       case DeviceConnectState::CONNECTING_AUTOCONNECT:
1423       case DeviceConnectState::DISCONNECTED:
1424         /* Do nothing, just remove device  */
1425         break;
1426     }
1427 
1428     /* Remove the group assignment if not yet removed. It might happen that the
1429      * group module has already called the appropriate callback and we have
1430      * already removed the group assignment.
1431      */
1432     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
1433       auto group = aseGroups_.FindById(leAudioDevice->group_id_);
1434       group_remove_node(group, address, true);
1435     }
1436 
1437     leAudioDevices_.Remove(address);
1438   }
1439 
Connect(const RawAddress & address)1440   void Connect(const RawAddress& address) override {
1441     log::info(": {}", address);
1442 
1443     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1444     if (!leAudioDevice) {
1445       if (!BTM_IsLinkKeyKnown(address, BT_TRANSPORT_LE)) {
1446         log::error("Connecting  {} when not bonded", address);
1447         callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
1448         return;
1449       }
1450       leAudioDevices_.Add(address, DeviceConnectState::CONNECTING_BY_USER);
1451     } else {
1452       auto current_connect_state = leAudioDevice->GetConnectionState();
1453       if ((current_connect_state == DeviceConnectState::CONNECTED) ||
1454           (current_connect_state == DeviceConnectState::CONNECTING_BY_USER)) {
1455         log::error("Device {} is in invalid state: {}", leAudioDevice->address_,
1456                    bluetooth::common::ToString(current_connect_state));
1457 
1458         return;
1459       }
1460 
1461       if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
1462         auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
1463         if (!group) {
1464           log::warn("{}, trying to connect to disabled group id {}", address,
1465                     leAudioDevice->group_id_);
1466           callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
1467           return;
1468         }
1469       }
1470 
1471       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTING_BY_USER);
1472 
1473       bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
1474           leAudioDevice->group_id_, address, ConnectionState::CONNECTING,
1475           bluetooth::le_audio::ConnectionStatus::SUCCESS);
1476     }
1477 
1478     BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
1479   }
1480 
GetGroupDevices(const int group_id)1481   std::vector<RawAddress> GetGroupDevices(const int group_id) override {
1482     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1483     std::vector<RawAddress> all_group_device_addrs;
1484 
1485     if (group != nullptr) {
1486       LeAudioDevice* leAudioDevice = group->GetFirstDevice();
1487       while (leAudioDevice) {
1488         all_group_device_addrs.push_back(leAudioDevice->address_);
1489         leAudioDevice = group->GetNextDevice(leAudioDevice);
1490       };
1491     }
1492 
1493     return all_group_device_addrs;
1494   }
1495 
1496   /* Restore paired device from storage to recreate groups */
AddFromStorage(const RawAddress & address,bool autoconnect,int sink_audio_location,int source_audio_location,int sink_supported_context_types,int source_supported_context_types,const std::vector<uint8_t> & handles,const std::vector<uint8_t> & sink_pacs,const std::vector<uint8_t> & source_pacs,const std::vector<uint8_t> & ases)1497   void AddFromStorage(const RawAddress& address, bool autoconnect,
1498                       int sink_audio_location, int source_audio_location,
1499                       int sink_supported_context_types,
1500                       int source_supported_context_types,
1501                       const std::vector<uint8_t>& handles,
1502                       const std::vector<uint8_t>& sink_pacs,
1503                       const std::vector<uint8_t>& source_pacs,
1504                       const std::vector<uint8_t>& ases) {
1505     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1506 
1507     if (leAudioDevice) {
1508       log::error("Device is already loaded. Nothing to do.");
1509       return;
1510     }
1511 
1512     log::info(
1513         "restoring: {}, autoconnect {}, sink_audio_location: {}, "
1514         "source_audio_location: {}, sink_supported_context_types : 0x{:04x}, "
1515         "source_supported_context_types 0x{:04x}",
1516         address, autoconnect, sink_audio_location, source_audio_location,
1517         sink_supported_context_types, source_supported_context_types);
1518 
1519     leAudioDevices_.Add(address, DeviceConnectState::DISCONNECTED);
1520     leAudioDevice = leAudioDevices_.FindByAddress(address);
1521 
1522     int group_id = DeviceGroups::Get()->GetGroupId(
1523         address, bluetooth::le_audio::uuid::kCapServiceUuid);
1524     if (group_id != bluetooth::groups::kGroupUnknown) {
1525       group_add_node(group_id, address);
1526     }
1527 
1528     leAudioDevice->snk_audio_locations_ = sink_audio_location;
1529     if (sink_audio_location != 0) {
1530       leAudioDevice->audio_directions_ |=
1531           bluetooth::le_audio::types::kLeAudioDirectionSink;
1532     }
1533 
1534     callbacks_->OnSinkAudioLocationAvailable(
1535         leAudioDevice->address_,
1536         leAudioDevice->snk_audio_locations_.to_ulong());
1537 
1538     leAudioDevice->src_audio_locations_ = source_audio_location;
1539     if (source_audio_location != 0) {
1540       leAudioDevice->audio_directions_ |=
1541           bluetooth::le_audio::types::kLeAudioDirectionSource;
1542     }
1543 
1544     BidirectionalPair<AudioContexts> supported_contexts = {
1545         .sink = AudioContexts(sink_supported_context_types),
1546         .source = AudioContexts(source_supported_context_types),
1547     };
1548 
1549     leAudioDevice->SetSupportedContexts(supported_contexts);
1550 
1551     /* Use same as supported ones for now. */
1552     leAudioDevice->SetAvailableContexts(supported_contexts);
1553 
1554     if (!DeserializeHandles(leAudioDevice, handles)) {
1555       log::warn("Could not load Handles");
1556     }
1557 
1558     if (!DeserializeSinkPacs(leAudioDevice, sink_pacs)) {
1559       /* If PACs are invalid, just say whole cache is invalid */
1560       leAudioDevice->known_service_handles_ = false;
1561       log::warn("Could not load sink pacs");
1562     }
1563 
1564     if (!DeserializeSourcePacs(leAudioDevice, source_pacs)) {
1565       /* If PACs are invalid, just say whole cache is invalid */
1566       leAudioDevice->known_service_handles_ = false;
1567       log::warn("Could not load source pacs");
1568     }
1569 
1570     if (!DeserializeAses(leAudioDevice, ases)) {
1571       /* If ASEs are invalid, just say whole cache is invalid */
1572       leAudioDevice->known_service_handles_ = false;
1573       log::warn("Could not load ases");
1574     }
1575 
1576     leAudioDevice->autoconnect_flag_ = autoconnect;
1577     /* When adding from storage, make sure that autoconnect is used
1578      * by all the devices in the group.
1579      */
1580     leAudioDevices_.SetInitialGroupAutoconnectState(
1581         group_id, gatt_if_, reconnection_mode_, autoconnect);
1582   }
1583 
GetHandlesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1584   bool GetHandlesForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
1585     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1586     return SerializeHandles(leAudioDevice, out);
1587   }
1588 
GetSinkPacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1589   bool GetSinkPacsForStorage(const RawAddress& addr,
1590                              std::vector<uint8_t>& out) {
1591     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1592     return SerializeSinkPacs(leAudioDevice, out);
1593   }
1594 
GetSourcePacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1595   bool GetSourcePacsForStorage(const RawAddress& addr,
1596                                std::vector<uint8_t>& out) {
1597     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1598     return SerializeSourcePacs(leAudioDevice, out);
1599   }
1600 
GetAsesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1601   bool GetAsesForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
1602     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1603 
1604     return SerializeAses(leAudioDevice, out);
1605   }
1606 
BackgroundConnectIfNeeded(LeAudioDevice * leAudioDevice)1607   void BackgroundConnectIfNeeded(LeAudioDevice* leAudioDevice) {
1608     if (!leAudioDevice->autoconnect_flag_) {
1609       log::debug("Device {} not in the background connect",
1610                  leAudioDevice->address_);
1611       return;
1612     }
1613     AddToBackgroundConnectCheckGroupConnected(leAudioDevice);
1614   }
1615 
Disconnect(const RawAddress & address)1616   void Disconnect(const RawAddress& address) override {
1617     log::info(": {}", address);
1618     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1619 
1620     if (!leAudioDevice) {
1621       log::warn("leAudioDevice not connected ( {} )", address);
1622       callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
1623       return;
1624     }
1625 
1626     auto connection_state = leAudioDevice->GetConnectionState();
1627     log::info("{}, state: {}", address,
1628               bluetooth::common::ToString(connection_state));
1629 
1630     switch (connection_state) {
1631       case DeviceConnectState::CONNECTING_BY_USER:
1632         /* Timeout happen on the Java layer. Device probably not in the range.
1633          * Cancel just direct connection and keep background if it is there.
1634          */
1635         BTA_GATTC_CancelOpen(gatt_if_, address, true);
1636         /* If this is a device which is a part of the group which is connected,
1637          * lets start backgroup connect
1638          */
1639         BackgroundConnectIfNeeded(leAudioDevice);
1640         return;
1641       case DeviceConnectState::CONNECTED: {
1642         /* User is disconnecting the device, we shall remove the autoconnect
1643          * flag for this device and all others if not TA is used
1644          */
1645         /* If target announcement is used, do not remove autoconnect
1646          */
1647         bool remove_from_autoconnect =
1648             (reconnection_mode_ != BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS);
1649 
1650         if (leAudioDevice->autoconnect_flag_ && remove_from_autoconnect) {
1651           log::info("Removing autoconnect flag for group_id {}",
1652                     leAudioDevice->group_id_);
1653 
1654           /* Removes device from background connect */
1655           BTA_GATTC_CancelOpen(gatt_if_, address, false);
1656           btif_storage_set_leaudio_autoconnect(address, false);
1657           leAudioDevice->autoconnect_flag_ = false;
1658         }
1659 
1660         /* Make sure ACL is disconnected to avoid reconnecting immediately
1661          * when autoconnect with TA reconnection mechanism is used.
1662          */
1663         bool force_acl_disconnect = leAudioDevice->autoconnect_flag_;
1664 
1665         auto group = aseGroups_.FindById(leAudioDevice->group_id_);
1666         if (group) {
1667           /* Remove devices from auto connect mode */
1668           for (auto dev = group->GetFirstDevice(); dev;
1669                dev = group->GetNextDevice(dev)) {
1670             if (remove_from_autoconnect &&
1671                 (dev->GetConnectionState() ==
1672                  DeviceConnectState::CONNECTING_AUTOCONNECT)) {
1673               btif_storage_set_leaudio_autoconnect(dev->address_, false);
1674               dev->autoconnect_flag_ = false;
1675               BTA_GATTC_CancelOpen(gatt_if_, dev->address_, false);
1676               dev->SetConnectionState(DeviceConnectState::DISCONNECTED);
1677             }
1678           }
1679           if (group->IsStreaming() || !group->IsReleasingOrIdle()) {
1680             leAudioDevice->closing_stream_for_disconnection_ = true;
1681             groupStateMachine_->StopStream(group);
1682             return;
1683           }
1684           force_acl_disconnect &= group->IsEnabled();
1685         }
1686 
1687         DisconnectDevice(leAudioDevice, force_acl_disconnect);
1688       }
1689         return;
1690       case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY:
1691         /* Timeout happen on the Java layer before native got ready with the
1692          * device */
1693         DisconnectDevice(leAudioDevice);
1694         return;
1695       case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY:
1696         /* Java is not aware about autoconnect actions,
1697          * therefore this should not happen.
1698          */
1699         log::warn("Should not happen - disconnect device");
1700         DisconnectDevice(leAudioDevice);
1701         return;
1702       case DeviceConnectState::DISCONNECTED:
1703       case DeviceConnectState::DISCONNECTING:
1704       case DeviceConnectState::DISCONNECTING_AND_RECOVER:
1705       case DeviceConnectState::CONNECTING_AUTOCONNECT:
1706       case DeviceConnectState::REMOVING:
1707         log::warn("{}, invalid state {}", address,
1708                   bluetooth::common::ToString(connection_state));
1709         return;
1710     }
1711   }
1712 
DisconnectDevice(LeAudioDevice * leAudioDevice,bool acl_force_disconnect=false,bool recover=false)1713   void DisconnectDevice(LeAudioDevice* leAudioDevice,
1714                         bool acl_force_disconnect = false,
1715                         bool recover = false) {
1716     if (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID) {
1717       return;
1718     }
1719 
1720     if (leAudioDevice->GetConnectionState() != DeviceConnectState::REMOVING) {
1721       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTING);
1722     }
1723 
1724     BtaGattQueue::Clean(leAudioDevice->conn_id_);
1725 
1726     /* Remote in bad state, force ACL Disconnection. */
1727     if (acl_force_disconnect) {
1728       leAudioDevice->DisconnectAcl();
1729       if (recover) {
1730         leAudioDevice->SetConnectionState(
1731             DeviceConnectState::DISCONNECTING_AND_RECOVER);
1732       }
1733     } else {
1734       BTA_GATTC_Close(leAudioDevice->conn_id_);
1735     }
1736   }
1737 
DeregisterNotifications(LeAudioDevice * leAudioDevice)1738   void DeregisterNotifications(LeAudioDevice* leAudioDevice) {
1739     /* GATTC will ommit not registered previously handles */
1740     for (auto pac_tuple : leAudioDevice->snk_pacs_) {
1741       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
1742                                            std::get<0>(pac_tuple).val_hdl);
1743     }
1744     for (auto pac_tuple : leAudioDevice->src_pacs_) {
1745       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
1746                                            std::get<0>(pac_tuple).val_hdl);
1747     }
1748 
1749     if (leAudioDevice->snk_audio_locations_hdls_.val_hdl != 0)
1750       BTA_GATTC_DeregisterForNotifications(
1751           gatt_if_, leAudioDevice->address_,
1752           leAudioDevice->snk_audio_locations_hdls_.val_hdl);
1753     if (leAudioDevice->src_audio_locations_hdls_.val_hdl != 0)
1754       BTA_GATTC_DeregisterForNotifications(
1755           gatt_if_, leAudioDevice->address_,
1756           leAudioDevice->src_audio_locations_hdls_.val_hdl);
1757     if (leAudioDevice->audio_avail_hdls_.val_hdl != 0)
1758       BTA_GATTC_DeregisterForNotifications(
1759           gatt_if_, leAudioDevice->address_,
1760           leAudioDevice->audio_avail_hdls_.val_hdl);
1761     if (leAudioDevice->audio_supp_cont_hdls_.val_hdl != 0)
1762       BTA_GATTC_DeregisterForNotifications(
1763           gatt_if_, leAudioDevice->address_,
1764           leAudioDevice->audio_supp_cont_hdls_.val_hdl);
1765     if (leAudioDevice->ctp_hdls_.val_hdl != 0)
1766       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
1767                                            leAudioDevice->ctp_hdls_.val_hdl);
1768 
1769     for (struct ase& ase : leAudioDevice->ases_)
1770       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
1771                                            ase.hdls.val_hdl);
1772   }
1773 
1774   /* This is a generic read/notify/indicate handler for gatt. Here messages
1775    * are dispatched to correct elements e.g. ASEs, PACs, audio locations etc.
1776    */
LeAudioCharValueHandle(uint16_t conn_id,uint16_t hdl,uint16_t len,uint8_t * value,bool notify=false)1777   void LeAudioCharValueHandle(uint16_t conn_id, uint16_t hdl, uint16_t len,
1778                               uint8_t* value, bool notify = false) {
1779     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
1780     struct ase* ase;
1781 
1782     if (!leAudioDevice) {
1783       log::error("no leAudioDevice assigned to connection id: {}",
1784                  static_cast<int>(conn_id));
1785       return;
1786     }
1787 
1788     ase = leAudioDevice->GetAseByValHandle(hdl);
1789 
1790     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
1791     if (ase) {
1792       groupStateMachine_->ProcessGattNotifEvent(value, len, ase, leAudioDevice,
1793                                                 group);
1794 
1795       return;
1796     }
1797 
1798     auto snk_pac_ent = std::find_if(
1799         leAudioDevice->snk_pacs_.begin(), leAudioDevice->snk_pacs_.end(),
1800         [&hdl](auto& pac_ent) { return std::get<0>(pac_ent).val_hdl == hdl; });
1801     if (snk_pac_ent != leAudioDevice->snk_pacs_.end()) {
1802       std::vector<struct bluetooth::le_audio::types::acs_ac_record> pac_recs;
1803 
1804       /* Guard consistency of PAC records structure */
1805       if (!bluetooth::le_audio::client_parser::pacs::ParsePacs(pac_recs, len,
1806                                                                value))
1807         return;
1808 
1809       log::info("Registering sink PACs");
1810       leAudioDevice->RegisterPACs(&std::get<1>(*snk_pac_ent), &pac_recs);
1811 
1812       /* Cached audio set configurations should be considered invalid when
1813        * PACs are updated.
1814        */
1815       if (group) {
1816         /* Changes in PAC record channel counts may change the strategy */
1817         group->InvalidateGroupStrategy();
1818         group->InvalidateCachedConfigurations();
1819       }
1820       if (notify) {
1821         btif_storage_leaudio_update_pacs_bin(leAudioDevice->address_);
1822       }
1823       return;
1824     }
1825 
1826     auto src_pac_ent = std::find_if(
1827         leAudioDevice->src_pacs_.begin(), leAudioDevice->src_pacs_.end(),
1828         [&hdl](auto& pac_ent) { return std::get<0>(pac_ent).val_hdl == hdl; });
1829     if (src_pac_ent != leAudioDevice->src_pacs_.end()) {
1830       std::vector<struct bluetooth::le_audio::types::acs_ac_record> pac_recs;
1831 
1832       /* Guard consistency of PAC records structure */
1833       if (!bluetooth::le_audio::client_parser::pacs::ParsePacs(pac_recs, len,
1834                                                                value))
1835         return;
1836 
1837       log::info("Registering source PACs");
1838       leAudioDevice->RegisterPACs(&std::get<1>(*src_pac_ent), &pac_recs);
1839 
1840       /* Cached audio set configurations should be considered invalid when
1841        * PACs are updated.
1842        */
1843       if (group) {
1844         /* Changes in PAC record channel counts may change the strategy */
1845         group->InvalidateGroupStrategy();
1846         group->InvalidateCachedConfigurations();
1847       }
1848       if (notify) {
1849         btif_storage_leaudio_update_pacs_bin(leAudioDevice->address_);
1850       }
1851       return;
1852     }
1853 
1854     if (hdl == leAudioDevice->snk_audio_locations_hdls_.val_hdl) {
1855       AudioLocations snk_audio_locations;
1856 
1857       bluetooth::le_audio::client_parser::pacs::ParseAudioLocations(
1858           snk_audio_locations, len, value);
1859 
1860       /* Value may not change */
1861       if ((leAudioDevice->audio_directions_ &
1862            bluetooth::le_audio::types::kLeAudioDirectionSink) &&
1863           (leAudioDevice->snk_audio_locations_ ^ snk_audio_locations).none())
1864         return;
1865 
1866       /* Presence of PAC characteristic for source means support for source
1867        * audio location. Value of 0x00000000 means mono/unspecified
1868        */
1869       leAudioDevice->audio_directions_ |=
1870           bluetooth::le_audio::types::kLeAudioDirectionSink;
1871       leAudioDevice->snk_audio_locations_ = snk_audio_locations;
1872 
1873       callbacks_->OnSinkAudioLocationAvailable(leAudioDevice->address_,
1874                                                snk_audio_locations.to_ulong());
1875 
1876       if (notify) {
1877         btif_storage_set_leaudio_audio_location(
1878             leAudioDevice->address_,
1879             leAudioDevice->snk_audio_locations_.to_ulong(),
1880             leAudioDevice->src_audio_locations_.to_ulong());
1881         if (group && group->IsReleasingOrIdle()) {
1882           UpdateLocationsAndContextsAvailability(group);
1883         }
1884       }
1885     } else if (hdl == leAudioDevice->src_audio_locations_hdls_.val_hdl) {
1886       AudioLocations src_audio_locations;
1887 
1888       bluetooth::le_audio::client_parser::pacs::ParseAudioLocations(
1889           src_audio_locations, len, value);
1890 
1891       /* Value may not change */
1892       if ((leAudioDevice->audio_directions_ &
1893            bluetooth::le_audio::types::kLeAudioDirectionSource) &&
1894           (leAudioDevice->src_audio_locations_ ^ src_audio_locations).none())
1895         return;
1896 
1897       /* Presence of PAC characteristic for source means support for source
1898        * audio location. Value of 0x00000000 means mono/unspecified
1899        */
1900       leAudioDevice->audio_directions_ |=
1901           bluetooth::le_audio::types::kLeAudioDirectionSource;
1902       leAudioDevice->src_audio_locations_ = src_audio_locations;
1903 
1904       if (notify) {
1905         btif_storage_set_leaudio_audio_location(
1906             leAudioDevice->address_,
1907             leAudioDevice->snk_audio_locations_.to_ulong(),
1908             leAudioDevice->src_audio_locations_.to_ulong());
1909         if (group && group->IsReleasingOrIdle()) {
1910           UpdateLocationsAndContextsAvailability(group);
1911         }
1912       }
1913     } else if (hdl == leAudioDevice->audio_avail_hdls_.val_hdl) {
1914       BidirectionalPair<AudioContexts> contexts;
1915       if (!bluetooth::le_audio::client_parser::pacs::
1916               ParseAvailableAudioContexts(contexts, len, value)) {
1917         return;
1918       }
1919 
1920       leAudioDevice->SetAvailableContexts(contexts);
1921 
1922       if (!group) {
1923         return;
1924       }
1925 
1926       if (group->IsInTransition()) {
1927         /* Group is in transition.
1928          * if group is going to stream, schedule attaching the device to the
1929          * group.
1930          */
1931 
1932         if (group->GetTargetState() ==
1933             AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
1934           AttachToStreamingGroupIfNeeded(leAudioDevice);
1935         }
1936         return;
1937       }
1938 
1939       if (!group->IsStreaming()) {
1940         /* Group is not streaming. Device does not have to be attach to the
1941          * stream, and we can update context availability for the group
1942          */
1943         UpdateLocationsAndContextsAvailability(group);
1944         return;
1945       }
1946 
1947       if (leAudioDevice->HaveActiveAse()) {
1948         /* Do nothing, device is streaming */
1949         return;
1950       }
1951 
1952       if (leAudioDevice->GetConnectionState() !=
1953           DeviceConnectState::CONNECTED) {
1954         /* Do nothing, wait until device is connected */
1955         return;
1956       }
1957 
1958       AttachToStreamingGroupIfNeeded(leAudioDevice);
1959 
1960     } else if (hdl == leAudioDevice->audio_supp_cont_hdls_.val_hdl) {
1961       BidirectionalPair<AudioContexts> supp_audio_contexts;
1962       if (bluetooth::le_audio::client_parser::pacs::ParseSupportedAudioContexts(
1963               supp_audio_contexts, len, value)) {
1964         /* Just store if for now */
1965         leAudioDevice->SetSupportedContexts(supp_audio_contexts);
1966 
1967         btif_storage_set_leaudio_supported_context_types(
1968             leAudioDevice->address_, supp_audio_contexts.sink.value(),
1969             supp_audio_contexts.source.value());
1970       }
1971     } else if (hdl == leAudioDevice->ctp_hdls_.val_hdl) {
1972       groupStateMachine_->ProcessGattCtpNotification(group, value, len);
1973     } else if (hdl == leAudioDevice->tmap_role_hdl_) {
1974       bluetooth::le_audio::client_parser::tmap::ParseTmapRole(
1975           leAudioDevice->tmap_role_, len, value);
1976     } else {
1977       log::error("Unknown attribute read: 0x{:x}", hdl);
1978     }
1979   }
1980 
OnGattReadRsp(uint16_t conn_id,tGATT_STATUS status,uint16_t hdl,uint16_t len,uint8_t * value,void * data)1981   void OnGattReadRsp(uint16_t conn_id, tGATT_STATUS status, uint16_t hdl,
1982                      uint16_t len, uint8_t* value, void* data) {
1983     LeAudioCharValueHandle(conn_id, hdl, len, value);
1984   }
1985 
GetGroupIfEnabled(int group_id)1986   LeAudioDeviceGroup* GetGroupIfEnabled(int group_id) {
1987     auto group = aseGroups_.FindById(group_id);
1988     if (group == nullptr) {
1989       log::info("Group {} does not exist", group_id);
1990       return nullptr;
1991     }
1992     if (!group->IsEnabled()) {
1993       log::info("Group {} is disabled", group_id);
1994       return nullptr;
1995     }
1996     return group;
1997   }
1998 
AddToBackgroundConnectCheckGroupConnected(LeAudioDevice * leAudioDevice)1999   void AddToBackgroundConnectCheckGroupConnected(LeAudioDevice* leAudioDevice) {
2000     /* If device belongs to streaming group, add it on allow list */
2001     auto address = leAudioDevice->address_;
2002     auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
2003     if (group == nullptr) {
2004       log::info("Group {} is invalid or disabled", leAudioDevice->group_id_);
2005       return;
2006     }
2007 
2008     leAudioDevice->SetConnectionState(
2009         DeviceConnectState::CONNECTING_AUTOCONNECT);
2010 
2011     /* Cancel previous bakcground connect */
2012     BTA_GATTC_CancelOpen(gatt_if_, address, false);
2013     if (group->IsAnyDeviceConnected()) {
2014       log::info("Group {} in connected state. Adding {} to allow list",
2015                 leAudioDevice->group_id_, address);
2016       BTA_GATTC_Open(gatt_if_, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
2017     } else {
2018       log::info(
2019           "Adding {} to backgroud connect (default reconnection_mode "
2020           "(0x{:02x}))",
2021           address, reconnection_mode_);
2022       BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false);
2023     }
2024   }
2025 
OnGattConnected(tGATT_STATUS status,uint16_t conn_id,tGATT_IF client_if,RawAddress address,tBT_TRANSPORT transport,uint16_t mtu)2026   void OnGattConnected(tGATT_STATUS status, uint16_t conn_id,
2027                        tGATT_IF client_if, RawAddress address,
2028                        tBT_TRANSPORT transport, uint16_t mtu) {
2029     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2030 
2031     log::info("{}, conn_id=0x{:04x}, transport={}, status={} (0x{:02x})",
2032               address, conn_id, bt_transport_text(transport),
2033               gatt_status_text(status), status);
2034 
2035     if (transport != BT_TRANSPORT_LE) {
2036       log::warn("Only LE connection is allowed (transport {})",
2037                 bt_transport_text(transport));
2038       BTA_GATTC_Close(conn_id);
2039       return;
2040     }
2041 
2042     if (!leAudioDevice) return;
2043 
2044     if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) {
2045       log::debug("Already connected {}, conn_id=0x{:04x}", address,
2046                  leAudioDevice->conn_id_);
2047       return;
2048     }
2049 
2050     if (status != GATT_SUCCESS) {
2051       /* Clear current connection request and let it be set again if needed */
2052       BTA_GATTC_CancelOpen(gatt_if_, address, false);
2053 
2054       /* autoconnect connection failed, that's ok */
2055       if (status != GATT_ILLEGAL_PARAMETER &&
2056           (leAudioDevice->GetConnectionState() ==
2057                DeviceConnectState::CONNECTING_AUTOCONNECT ||
2058            leAudioDevice->autoconnect_flag_)) {
2059         log::info("Device not available now, do background connect.");
2060         leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2061         AddToBackgroundConnectCheckGroupConnected(leAudioDevice);
2062         return;
2063       }
2064 
2065       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2066 
2067       log::error("Failed to connect to LeAudio leAudioDevice, status: 0x{:02x}",
2068                  status);
2069       callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
2070       bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2071           leAudioDevice->group_id_, address, ConnectionState::CONNECTED,
2072           bluetooth::le_audio::ConnectionStatus::FAILED);
2073       return;
2074     }
2075 
2076     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
2077       auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
2078       if (group == nullptr) {
2079         BTA_GATTC_CancelOpen(gatt_if_, address, false);
2080 
2081         log::warn(
2082             "LeAudio profile is disabled for group_id: {}. {} is not connected",
2083             leAudioDevice->group_id_, address);
2084         return;
2085       }
2086     }
2087 
2088     leAudioDevice->conn_id_ = conn_id;
2089     leAudioDevice->mtu_ = mtu;
2090 
2091     /* Remove device from the background connect (it might be either Allow list
2092      * or TA) and add it again with reconnection_mode_. In case it is TA, we are
2093      * sure that device will not be in the allow list for other applications
2094      * which are using background connect.
2095      */
2096     BTA_GATTC_CancelOpen(gatt_if_, address, false);
2097     BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false);
2098 
2099     if (bluetooth::shim::GetController()->SupportsBle2mPhy()) {
2100       log::info("{} set preferred PHY to 2M", address);
2101       BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
2102     }
2103 
2104     BTM_RequestPeerSCA(leAudioDevice->address_, transport);
2105 
2106     if (leAudioDevice->GetConnectionState() ==
2107         DeviceConnectState::CONNECTING_AUTOCONNECT) {
2108       leAudioDevice->SetConnectionState(
2109           DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY);
2110     } else {
2111       leAudioDevice->SetConnectionState(
2112           DeviceConnectState::CONNECTED_BY_USER_GETTING_READY);
2113     }
2114 
2115     /* Check if the device is in allow list and update the flag */
2116     leAudioDevice->UpdateDeviceAllowlistFlag();
2117     if (BTM_SecIsSecurityPending(address)) {
2118       /* if security collision happened, wait for encryption done
2119        * (BTA_GATTC_ENC_CMPL_CB_EVT) */
2120       return;
2121     }
2122 
2123     /* verify bond */
2124     if (BTM_IsEncrypted(address, BT_TRANSPORT_LE)) {
2125       /* if link has been encrypted */
2126       OnEncryptionComplete(address, BTM_SUCCESS);
2127       return;
2128     }
2129 
2130     int result = BTM_SetEncryption(address, BT_TRANSPORT_LE, nullptr, nullptr,
2131                                    BTM_BLE_SEC_ENCRYPT);
2132 
2133     log::info("Encryption required for {}. Request result: 0x{:02x}", address,
2134               result);
2135 
2136     if (result == BTM_ERR_KEY_MISSING) {
2137       log::error("Link key unknown for {}, disconnect profile", address);
2138       bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2139           leAudioDevice->group_id_, address, ConnectionState::CONNECTED,
2140           bluetooth::le_audio::ConnectionStatus::FAILED);
2141 
2142       /* If link cannot be enctypted, disconnect profile */
2143       BTA_GATTC_Close(conn_id);
2144     }
2145   }
2146 
RegisterKnownNotifications(LeAudioDevice * leAudioDevice,bool gatt_register,bool write_ccc)2147   void RegisterKnownNotifications(LeAudioDevice* leAudioDevice,
2148                                   bool gatt_register, bool write_ccc) {
2149     log::info("device: {}", leAudioDevice->address_);
2150 
2151     if (leAudioDevice->ctp_hdls_.val_hdl == 0) {
2152       log::error(
2153           "Control point characteristic is mandatory - disconnecting device {}",
2154           leAudioDevice->address_);
2155       DisconnectDevice(leAudioDevice);
2156       return;
2157     }
2158 
2159     /* GATTC will ommit not registered previously handles */
2160     for (auto pac_tuple : leAudioDevice->snk_pacs_) {
2161       subscribe_for_notification(
2162           leAudioDevice->conn_id_, leAudioDevice->address_,
2163           std::get<0>(pac_tuple), gatt_register, write_ccc);
2164     }
2165     for (auto pac_tuple : leAudioDevice->src_pacs_) {
2166       subscribe_for_notification(
2167           leAudioDevice->conn_id_, leAudioDevice->address_,
2168           std::get<0>(pac_tuple), gatt_register, write_ccc);
2169     }
2170 
2171     if (leAudioDevice->snk_audio_locations_hdls_.val_hdl != 0)
2172       subscribe_for_notification(
2173           leAudioDevice->conn_id_, leAudioDevice->address_,
2174           leAudioDevice->snk_audio_locations_hdls_, gatt_register, write_ccc);
2175     if (leAudioDevice->src_audio_locations_hdls_.val_hdl != 0)
2176       subscribe_for_notification(
2177           leAudioDevice->conn_id_, leAudioDevice->address_,
2178           leAudioDevice->src_audio_locations_hdls_, gatt_register, write_ccc);
2179 
2180     if (leAudioDevice->audio_avail_hdls_.val_hdl != 0)
2181       subscribe_for_notification(
2182           leAudioDevice->conn_id_, leAudioDevice->address_,
2183           leAudioDevice->audio_avail_hdls_, gatt_register, write_ccc);
2184 
2185     if (leAudioDevice->audio_supp_cont_hdls_.val_hdl != 0)
2186       subscribe_for_notification(
2187           leAudioDevice->conn_id_, leAudioDevice->address_,
2188           leAudioDevice->audio_supp_cont_hdls_, gatt_register, write_ccc);
2189 
2190     for (struct ase& ase : leAudioDevice->ases_)
2191       subscribe_for_notification(leAudioDevice->conn_id_,
2192                                  leAudioDevice->address_, ase.hdls,
2193                                  gatt_register, write_ccc);
2194 
2195     subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2196                                leAudioDevice->ctp_hdls_, gatt_register,
2197                                write_ccc);
2198   }
2199 
changeMtuIfPossible(LeAudioDevice * leAudioDevice)2200   void changeMtuIfPossible(LeAudioDevice* leAudioDevice) {
2201     if (leAudioDevice->mtu_ == GATT_DEF_BLE_MTU_SIZE) {
2202       log::info("Configure MTU");
2203       /* Use here kBapMinimumAttMtu, because we know that GATT will request
2204        * default ATT MTU anyways. We also know that GATT will use this
2205        * kBapMinimumAttMtu as an input for Data Length Update procedure in the controller.
2206        */
2207       BtaGattQueue::ConfigureMtu(leAudioDevice->conn_id_, kBapMinimumAttMtu);
2208     }
2209   }
2210 
OnEncryptionComplete(const RawAddress & address,uint8_t status)2211   void OnEncryptionComplete(const RawAddress& address, uint8_t status) {
2212     log::info("{} status 0x{:02x}", address, status);
2213     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2214     if (leAudioDevice == NULL ||
2215         (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID)) {
2216       log::warn("Skipping device which is {}",
2217                 leAudioDevice ? " not connected by service." : " null");
2218       return;
2219     }
2220 
2221     if (status != BTM_SUCCESS) {
2222       log::error("Encryption failed status: {}", int{status});
2223       if (leAudioDevice->GetConnectionState() ==
2224           DeviceConnectState::CONNECTED_BY_USER_GETTING_READY) {
2225         callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
2226         bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2227             leAudioDevice->group_id_, address, ConnectionState::CONNECTED,
2228             bluetooth::le_audio::ConnectionStatus::FAILED);
2229       }
2230 
2231       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTING);
2232 
2233       BTA_GATTC_Close(leAudioDevice->conn_id_);
2234       return;
2235     }
2236 
2237     if (leAudioDevice->encrypted_) {
2238       log::info("link already encrypted, nothing to do");
2239       return;
2240     }
2241 
2242     /* If PHY update did not succeed after ACL connection, which can happen
2243      * when remote feature read was not that quick, lets try to change phy here
2244      * one more time
2245      */
2246     if (!leAudioDevice->acl_phy_update_done_ &&
2247         bluetooth::shim::GetController()->SupportsBle2mPhy()) {
2248       log::info("{} set preferred PHY to 2M", leAudioDevice->address_);
2249       BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
2250     }
2251 
2252     changeMtuIfPossible(leAudioDevice);
2253 
2254     leAudioDevice->encrypted_ = true;
2255 
2256     /* If we know services, register for notifications */
2257     if (leAudioDevice->known_service_handles_) {
2258       /* This registration will do subscribtion in local GATT as we
2259        * assume remote device keeps bonded CCC values.
2260        */
2261       RegisterKnownNotifications(leAudioDevice, true, false);
2262 
2263       /* Make sure remote keeps CCC values as per specification.
2264        * We read only ctp_ccc value. If that one is good, we assume
2265        * remote keeps CCC values correctly.
2266        */
2267       BtaGattQueue::ReadCharacteristic(leAudioDevice->conn_id_,
2268                                        leAudioDevice->ctp_hdls_.ccc_hdl,
2269                                        OnGattCtpCccReadRspStatic, NULL);
2270     }
2271 
2272     /* If we know services and read is not ongoing, this is reconnection and
2273      * just notify connected  */
2274     if (leAudioDevice->known_service_handles_ &&
2275         !leAudioDevice->notify_connected_after_read_) {
2276       log::info("Wait for CCC registration and MTU change request");
2277       return;
2278     }
2279 
2280     BTA_GATTC_ServiceSearchRequest(
2281         leAudioDevice->conn_id_,
2282         bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid);
2283   }
2284 
checkGroupConnectionStateAfterMemberDisconnect(int group_id)2285   void checkGroupConnectionStateAfterMemberDisconnect(int group_id) {
2286     /* This is fired t=kGroupConnectedWatchDelayMs after group member
2287      * got disconencted while ather group members were connected.
2288      * We want to check here if there is any group member connected.
2289      * If so we should add other group members to allow list for better
2290      * reconnection experiance. If  all group members are disconnected
2291      * i e.g. devices intentionally disconnected for other
2292      * purposes like pairing with other device, then we do nothing here and
2293      * device stay on the default reconnection policy (i.e. targeted
2294      * announcements)
2295      */
2296     auto group = aseGroups_.FindById(group_id);
2297     if (group == nullptr) {
2298       log::info("Group {} is destroyed.", group_id);
2299       return;
2300     }
2301 
2302     if (!group->IsAnyDeviceConnected()) {
2303       log::info("Group {} is not connected", group_id);
2304       /* Make sure all devices are in the default reconnection mode */
2305       group->ApplyReconnectionMode(gatt_if_, reconnection_mode_);
2306       return;
2307     }
2308 
2309     /* if group is still connected, make sure that other not connected
2310      * set members are in the allow list for the quick reconnect.
2311      * E.g. for the earbud case, probably one of the earbud is in the case now.
2312      */
2313     group->AddToAllowListNotConnectedGroupMembers(gatt_if_);
2314   }
2315 
scheduleGroupConnectedCheck(int group_id)2316   void scheduleGroupConnectedCheck(int group_id) {
2317     log::info("Schedule group_id {} connected check.", group_id);
2318     do_in_main_thread_delayed(
2319         FROM_HERE,
2320         base::BindOnce(
2321             &LeAudioClientImpl::checkGroupConnectionStateAfterMemberDisconnect,
2322             weak_factory_.GetWeakPtr(), group_id),
2323         std::chrono::milliseconds(kGroupConnectedWatchDelayMs));
2324   }
2325 
autoConnect(RawAddress address)2326   void autoConnect(RawAddress address) {
2327     auto leAudioDevice = leAudioDevices_.FindByAddress(address);
2328     if (leAudioDevice == nullptr) {
2329       log::warn("Device {} not valid anymore", address);
2330       return;
2331     }
2332 
2333     BackgroundConnectIfNeeded(leAudioDevice);
2334   }
2335 
scheduleAutoConnect(RawAddress & address)2336   void scheduleAutoConnect(RawAddress& address) {
2337     log::info("Schedule auto connect {}", address);
2338     do_in_main_thread_delayed(
2339         FROM_HERE,
2340         base::BindOnce(&LeAudioClientImpl::autoConnect,
2341                        weak_factory_.GetWeakPtr(), address),
2342         std::chrono::milliseconds(kAutoConnectAfterOwnDisconnectDelayMs));
2343   }
2344 
recoveryReconnect(RawAddress address)2345   void recoveryReconnect(RawAddress address) {
2346     log::info("Reconnecting to {} after timeout on state machine.", address);
2347     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2348 
2349     if (leAudioDevice == nullptr ||
2350         leAudioDevice->GetConnectionState() !=
2351             DeviceConnectState::DISCONNECTING_AND_RECOVER) {
2352       log::warn("Device {}, not interested in recovery connect anymore",
2353                 address);
2354       return;
2355     }
2356 
2357     auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
2358 
2359     if (group != nullptr) {
2360       leAudioDevice->SetConnectionState(
2361           DeviceConnectState::CONNECTING_AUTOCONNECT);
2362       BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
2363     } else {
2364       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2365     }
2366   }
2367 
scheduleRecoveryReconnect(RawAddress & address)2368   void scheduleRecoveryReconnect(RawAddress& address) {
2369     log::info("Schedule reconnecting to {} after timeout on state machine.",
2370               address);
2371     do_in_main_thread_delayed(
2372         FROM_HERE,
2373         base::BindOnce(&LeAudioClientImpl::recoveryReconnect,
2374                        weak_factory_.GetWeakPtr(), address),
2375         std::chrono::milliseconds(kRecoveryReconnectDelayMs));
2376   }
2377 
checkIfGroupMember(RawAddress address)2378   void checkIfGroupMember(RawAddress address) {
2379     log::info("checking being a group member: {}", address);
2380     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2381 
2382     if (leAudioDevice == nullptr) {
2383       log::warn("Device {}, probably removed", address);
2384       return;
2385     }
2386 
2387     if (leAudioDevice->group_id_ == bluetooth::groups::kGroupUnknown) {
2388       disconnectInvalidDevice(leAudioDevice,
2389                               ", device not a valid group member",
2390                               LeAudioHealthDeviceStatType::INVALID_CSIS);
2391       return;
2392     }
2393   }
2394 
2395   /* This is called, when CSIS native module is about to add device to the
2396    * group once the CSIS service will be verified on the remote side.
2397    * After some time (kCsisGroupMemberDelayMs)  a checkIfGroupMember will be
2398    * called and will verify if the remote device has a group_id properly set.
2399    * if not, it means there is something wrong with CSIS service on the remote
2400    * side.
2401    */
scheduleGuardForCsisAdd(RawAddress & address)2402   void scheduleGuardForCsisAdd(RawAddress& address) {
2403     log::info("Schedule reconnecting to {} after timeout on state machine.",
2404               address);
2405     do_in_main_thread_delayed(
2406         FROM_HERE,
2407         base::BindOnce(&LeAudioClientImpl::checkIfGroupMember,
2408                        weak_factory_.GetWeakPtr(), address),
2409         std::chrono::milliseconds(kCsisGroupMemberDelayMs));
2410   }
2411 
OnGattDisconnected(uint16_t conn_id,tGATT_IF client_if,RawAddress address,tGATT_DISCONN_REASON reason)2412   void OnGattDisconnected(uint16_t conn_id, tGATT_IF client_if,
2413                           RawAddress address, tGATT_DISCONN_REASON reason) {
2414     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2415 
2416     if (!leAudioDevice) {
2417       log::error(", skipping unknown leAudioDevice, address: {}", address);
2418       return;
2419     }
2420 
2421     leAudioDevice->acl_asymmetric_ = false;
2422     BtaGattQueue::Clean(leAudioDevice->conn_id_);
2423     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
2424 
2425     DeregisterNotifications(leAudioDevice);
2426 
2427     callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
2428     leAudioDevice->conn_id_ = GATT_INVALID_CONN_ID;
2429     leAudioDevice->mtu_ = 0;
2430     leAudioDevice->closing_stream_for_disconnection_ = false;
2431     leAudioDevice->encrypted_ = false;
2432     leAudioDevice->acl_phy_update_done_ = false;
2433 
2434     groupStateMachine_->ProcessHciNotifAclDisconnected(group, leAudioDevice);
2435 
2436     bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2437         leAudioDevice->group_id_, address, ConnectionState::DISCONNECTED,
2438         bluetooth::le_audio::ConnectionStatus::SUCCESS);
2439 
2440     if (leAudioDevice->GetConnectionState() == DeviceConnectState::REMOVING) {
2441       if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
2442         auto group = aseGroups_.FindById(leAudioDevice->group_id_);
2443         group_remove_node(group, address, true);
2444       }
2445       leAudioDevices_.Remove(address);
2446       return;
2447     }
2448 
2449     auto connection_state = leAudioDevice->GetConnectionState();
2450     log::info("{}, autoconnect {}, reason 0x{:02x}, connection state {}",
2451               leAudioDevice->address_, leAudioDevice->autoconnect_flag_, reason,
2452               bluetooth::common::ToString(connection_state));
2453 
2454     if (connection_state == DeviceConnectState::DISCONNECTING_AND_RECOVER) {
2455       /* We are back after disconnecting device which was in a bad state.
2456        * lets try to reconnected - 30 sec with direct connect and later fallback
2457        * to default background reconnection mode.
2458        * Since GATT notifies us before ACL was dropped, let's wait a bit
2459        * before we do reconnect.
2460        */
2461       scheduleRecoveryReconnect(address);
2462       return;
2463     }
2464 
2465     leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2466 
2467     /* Attempt background re-connect if disconnect was not initiated locally
2468      * or if autoconnect is set and device got disconnected because of some
2469      * issues
2470      */
2471     if (group == nullptr || !group->IsEnabled()) {
2472       log::error("Group id {} ({}) disabled or null", leAudioDevice->group_id_,
2473                  fmt::ptr(group));
2474       return;
2475     }
2476 
2477     if (reason == GATT_CONN_TERMINATE_LOCAL_HOST) {
2478       if (leAudioDevice->autoconnect_flag_) {
2479         /* In this case ACL might not yet been disconnected */
2480         scheduleAutoConnect(address);
2481       }
2482       return;
2483     }
2484 
2485     /* Remote disconnects from us or Timeout happens */
2486     /* In this case ACL is disconnected */
2487     if (reason == GATT_CONN_TIMEOUT) {
2488       leAudioDevice->SetConnectionState(
2489           DeviceConnectState::CONNECTING_AUTOCONNECT);
2490 
2491       /* If timeout try to reconnect for 30 sec.*/
2492       BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
2493       return;
2494     }
2495 
2496     /* In other disconnect resons we act based on the autoconnect_flag_ */
2497     if (leAudioDevice->autoconnect_flag_) {
2498       if (group->IsAnyDeviceConnected()) {
2499         /* If all set is disconnecting, let's give it some time.
2500          * If not all get disconnected, and there will be group member
2501          * connected we want to put disconnected devices to allow list
2502          */
2503         scheduleGroupConnectedCheck(leAudioDevice->group_id_);
2504       } else {
2505         group->ApplyReconnectionMode(gatt_if_, reconnection_mode_);
2506       }
2507     }
2508   }
2509 
subscribe_for_notification(uint16_t conn_id,const RawAddress & address,struct bluetooth::le_audio::types::hdl_pair handle_pair,bool gatt_register=true,bool write_ccc=true)2510   bool subscribe_for_notification(
2511       uint16_t conn_id, const RawAddress& address,
2512       struct bluetooth::le_audio::types::hdl_pair handle_pair,
2513       bool gatt_register = true, bool write_ccc = true) {
2514     std::vector<uint8_t> value(2);
2515     uint8_t* ptr = value.data();
2516     uint16_t handle = handle_pair.val_hdl;
2517     uint16_t ccc_handle = handle_pair.ccc_hdl;
2518 
2519     log::info("conn id {}, gatt_register: {}, write_ccc: {}", conn_id,
2520               gatt_register, write_ccc);
2521     if (gatt_register && BTA_GATTC_RegisterForNotifications(
2522                              gatt_if_, address, handle) != GATT_SUCCESS) {
2523       log::error("cannot register for notification: {}",
2524                  static_cast<int>(handle));
2525       return false;
2526     }
2527 
2528     if (write_ccc == false) {
2529       log::verbose("CCC is not written to {} (0x{:04x}), handle 0x{:04x}",
2530                    address, conn_id, ccc_handle);
2531       return true;
2532     }
2533 
2534     UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
2535 
2536     BtaGattQueue::WriteDescriptor(
2537         conn_id, ccc_handle, std::move(value), GATT_WRITE,
2538         [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
2539            const uint8_t* value, void* data) {
2540           if (instance) instance->OnGattWriteCcc(conn_id, status, handle, data);
2541         },
2542         nullptr);
2543     return true;
2544   }
2545 
2546   /* Find the handle for the client characteristics configuration of a given
2547    * characteristics.
2548    */
find_ccc_handle(const gatt::Characteristic & charac)2549   uint16_t find_ccc_handle(const gatt::Characteristic& charac) {
2550     auto iter = std::find_if(
2551         charac.descriptors.begin(), charac.descriptors.end(),
2552         [](const auto& desc) {
2553           return desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG);
2554         });
2555 
2556     return iter == charac.descriptors.end() ? 0 : (*iter).handle;
2557   }
2558 
ClearDeviceInformationAndStartSearch(LeAudioDevice * leAudioDevice)2559   void ClearDeviceInformationAndStartSearch(LeAudioDevice* leAudioDevice) {
2560     if (!leAudioDevice) {
2561       log::warn("leAudioDevice is null");
2562       return;
2563     }
2564 
2565     log::info("{}", leAudioDevice->address_);
2566 
2567     if (leAudioDevice->known_service_handles_ == false) {
2568       log::debug("Database already invalidated");
2569       return;
2570     }
2571 
2572     leAudioDevice->known_service_handles_ = false;
2573     leAudioDevice->csis_member_ = false;
2574     BtaGattQueue::Clean(leAudioDevice->conn_id_);
2575     DeregisterNotifications(leAudioDevice);
2576 
2577     if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTED) {
2578       leAudioDevice->SetConnectionState(
2579           DeviceConnectState::CONNECTED_BY_USER_GETTING_READY);
2580     }
2581 
2582     btif_storage_leaudio_clear_service_data(leAudioDevice->address_);
2583 
2584     BTA_GATTC_ServiceSearchRequest(
2585         leAudioDevice->conn_id_,
2586         bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid);
2587   }
2588 
OnServiceChangeEvent(const RawAddress & address)2589   void OnServiceChangeEvent(const RawAddress& address) {
2590     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2591     if (!leAudioDevice) {
2592       log::warn("Skipping unknown leAudioDevice {} ({})", address,
2593                 fmt::ptr(leAudioDevice));
2594       return;
2595     }
2596 
2597     if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) {
2598       ClearDeviceInformationAndStartSearch(leAudioDevice);
2599       return;
2600     }
2601 
2602     /* If device is not connected, just clear the handle information and this
2603      * will trigger service search onGattConnected */
2604     leAudioDevice->known_service_handles_ = false;
2605     btif_storage_leaudio_clear_service_data(address);
2606   }
2607 
OnMtuChanged(uint16_t conn_id,uint16_t mtu)2608   void OnMtuChanged(uint16_t conn_id, uint16_t mtu) {
2609     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2610     if (!leAudioDevice) {
2611       log::debug("Unknown connectect id {}", conn_id);
2612       return;
2613     }
2614 
2615     /**
2616      * BAP 1.01. 3.6.1
2617      * ATT and EATT transport requirements
2618      * The Unicast Client shall support a minimum ATT_MTU of 64 octets for one
2619      * Unenhanced ATT bearer, or for at least one Enhanced ATT bearer if the
2620      * Unicast Client supports Enhanced ATT bearers.
2621      *
2622      */
2623     if (mtu < 64) {
2624       log::error("Device {} MTU is too low ({}). Disconnecting from LE Audio",
2625                  leAudioDevice->address_, mtu);
2626       Disconnect(leAudioDevice->address_);
2627       return;
2628     }
2629 
2630     leAudioDevice->mtu_ = mtu;
2631   }
2632 
OnPhyUpdate(uint16_t conn_id,uint8_t tx_phy,uint8_t rx_phy,tGATT_STATUS status)2633   void OnPhyUpdate(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
2634                    tGATT_STATUS status) {
2635     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2636     if (leAudioDevice == nullptr) {
2637       log::debug("Unknown conn_id {:#x}", conn_id);
2638       return;
2639     }
2640 
2641     log::info("{}, tx_phy: {:#x}, rx_phy: {:#x} , status: {:#x}",
2642               leAudioDevice->address_, tx_phy, rx_phy, status);
2643 
2644     if (status == 0) {
2645       leAudioDevice->acl_phy_update_done_ = true;
2646     }
2647   }
2648 
OnGattServiceDiscoveryDone(const RawAddress & address)2649   void OnGattServiceDiscoveryDone(const RawAddress& address) {
2650     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2651     if (!leAudioDevice || (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID)) {
2652       log::verbose("skipping unknown leAudioDevice, address {} ({})", address,
2653                    fmt::ptr(leAudioDevice));
2654       return;
2655     }
2656 
2657     if (!leAudioDevice->encrypted_) {
2658       log::debug("Wait for device to be encrypted");
2659       return;
2660     }
2661 
2662     if (!leAudioDevice->known_service_handles_)
2663       BTA_GATTC_ServiceSearchRequest(
2664           leAudioDevice->conn_id_,
2665           bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid);
2666   }
2667 
disconnectInvalidDevice(LeAudioDevice * leAudioDevice,std::string error_string,LeAudioHealthDeviceStatType stat)2668   void disconnectInvalidDevice(LeAudioDevice* leAudioDevice,
2669                                std::string error_string,
2670                                LeAudioHealthDeviceStatType stat) {
2671     log::error("{}, {}", leAudioDevice->address_, error_string);
2672     if (leAudioHealthStatus_) {
2673       leAudioHealthStatus_->AddStatisticForDevice(leAudioDevice, stat);
2674     }
2675     DisconnectDevice(leAudioDevice);
2676   }
2677 
2678   /* This method is called after connection beginning to identify and initialize
2679    * a le audio device. Any missing mandatory attribute will result in reverting
2680    * and cleaning up device.
2681    */
OnServiceSearchComplete(uint16_t conn_id,tGATT_STATUS status)2682   void OnServiceSearchComplete(uint16_t conn_id, tGATT_STATUS status) {
2683     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2684 
2685     if (!leAudioDevice) {
2686       log::error("skipping unknown leAudioDevice, conn_id: 0x{:x}", conn_id);
2687       return;
2688     }
2689 
2690     log::info("test csis_member {}", leAudioDevice->csis_member_);
2691 
2692     if (status != GATT_SUCCESS) {
2693       /* close connection and report service discovery complete with error */
2694       log::error("Service discovery failed");
2695 
2696       DisconnectDevice(leAudioDevice);
2697       return;
2698     }
2699 
2700     if (!leAudioDevice->encrypted_) {
2701       log::warn("Device not yet bonded - waiting for encryption");
2702       return;
2703     }
2704 
2705     const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
2706 
2707     const gatt::Service* pac_svc = nullptr;
2708     const gatt::Service* ase_svc = nullptr;
2709     const gatt::Service* tmas_svc = nullptr;
2710 
2711     std::vector<uint16_t> csis_primary_handles;
2712     uint16_t cas_csis_included_handle = 0;
2713 
2714     for (const gatt::Service& tmp : *services) {
2715       if (tmp.uuid ==
2716           bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid) {
2717         log::info(
2718             "Found Audio Capability service, handle: 0x{:04x}, device: {}",
2719             tmp.handle, leAudioDevice->address_);
2720         pac_svc = &tmp;
2721       } else if (tmp.uuid ==
2722                  bluetooth::le_audio::uuid::kAudioStreamControlServiceUuid) {
2723         log::info(
2724             "Found Audio Stream Endpoint service, handle: 0x{:04x}, device: {}",
2725             tmp.handle, leAudioDevice->address_);
2726         ase_svc = &tmp;
2727       } else if (tmp.uuid == bluetooth::csis::kCsisServiceUuid) {
2728         log::info(
2729             "Found CSIS service, handle: 0x{:04x}, is primary: {}, device: {}",
2730             tmp.handle, tmp.is_primary, leAudioDevice->address_);
2731         if (tmp.is_primary) csis_primary_handles.push_back(tmp.handle);
2732       } else if (tmp.uuid == bluetooth::le_audio::uuid::kCapServiceUuid) {
2733         log::info("Found CAP service, handle: 0x{:04x}, device: {}", tmp.handle,
2734                   leAudioDevice->address_);
2735 
2736         /* Try to find context for CSIS instances */
2737         for (auto& included_srvc : tmp.included_services) {
2738           if (included_srvc.uuid == bluetooth::csis::kCsisServiceUuid) {
2739             log::info("CSIS included into CAS");
2740             if (bluetooth::csis::CsisClient::IsCsisClientRunning())
2741               cas_csis_included_handle = included_srvc.start_handle;
2742 
2743             break;
2744           }
2745         }
2746       } else if (tmp.uuid ==
2747                  bluetooth::le_audio::uuid::kTelephonyMediaAudioServiceUuid) {
2748         log::info(
2749             "Found Telephony and Media Audio service, handle: 0x{:04x}, "
2750             "device: {}",
2751             tmp.handle, leAudioDevice->address_);
2752         tmas_svc = &tmp;
2753       }
2754     }
2755 
2756     /* Check if CAS includes primary CSIS service */
2757     if (!csis_primary_handles.empty() && cas_csis_included_handle) {
2758       auto iter =
2759           std::find(csis_primary_handles.begin(), csis_primary_handles.end(),
2760                     cas_csis_included_handle);
2761       if (iter != csis_primary_handles.end())
2762         leAudioDevice->csis_member_ = true;
2763     }
2764 
2765     if (!pac_svc || !ase_svc) {
2766       disconnectInvalidDevice(
2767           leAudioDevice, "No mandatory le audio services found (pacs or ascs)",
2768           LeAudioHealthDeviceStatType::INVALID_DB);
2769       return;
2770     }
2771 
2772     /* Refresh PACs handles */
2773     leAudioDevice->ClearPACs();
2774 
2775     for (const gatt::Characteristic& charac : pac_svc->characteristics) {
2776       if (charac.uuid == bluetooth::le_audio::uuid::
2777                              kSinkPublishedAudioCapabilityCharacteristicUuid) {
2778         struct hdl_pair hdl_pair;
2779         hdl_pair.val_hdl = charac.value_handle;
2780         hdl_pair.ccc_hdl = find_ccc_handle(charac);
2781 
2782         if (hdl_pair.ccc_hdl == 0) {
2783           log::info(", Sink PACs ccc not available");
2784         }
2785 
2786         if (hdl_pair.ccc_hdl != 0 &&
2787             !subscribe_for_notification(conn_id, leAudioDevice->address_,
2788                                         hdl_pair)) {
2789           disconnectInvalidDevice(leAudioDevice,
2790                                   ", cound not subscribe for snk pac char",
2791                                   LeAudioHealthDeviceStatType::INVALID_DB);
2792           return;
2793         }
2794 
2795         /* Obtain initial state of sink PACs */
2796         BtaGattQueue::ReadCharacteristic(conn_id, hdl_pair.val_hdl,
2797                                          OnGattReadRspStatic, NULL);
2798 
2799         leAudioDevice->snk_pacs_.push_back(std::make_tuple(
2800             hdl_pair,
2801             std::vector<struct bluetooth::le_audio::types::acs_ac_record>()));
2802 
2803         log::info(
2804             "Found Sink PAC characteristic, handle: 0x{:04x}, ccc handle: "
2805             "0x{:04x}, addr: {}",
2806             charac.value_handle, hdl_pair.ccc_hdl, leAudioDevice->address_);
2807       } else if (charac.uuid ==
2808                  bluetooth::le_audio::uuid::
2809                      kSourcePublishedAudioCapabilityCharacteristicUuid) {
2810         struct hdl_pair hdl_pair;
2811         hdl_pair.val_hdl = charac.value_handle;
2812         hdl_pair.ccc_hdl = find_ccc_handle(charac);
2813 
2814         if (hdl_pair.ccc_hdl == 0) {
2815           log::info(", Source PACs ccc not available");
2816         }
2817 
2818         if (hdl_pair.ccc_hdl != 0 &&
2819             !subscribe_for_notification(conn_id, leAudioDevice->address_,
2820                                         hdl_pair)) {
2821           disconnectInvalidDevice(leAudioDevice,
2822                                   ", could not subscribe for src pac char",
2823                                   LeAudioHealthDeviceStatType::INVALID_DB);
2824           return;
2825         }
2826 
2827         /* Obtain initial state of source PACs */
2828         BtaGattQueue::ReadCharacteristic(conn_id, hdl_pair.val_hdl,
2829                                          OnGattReadRspStatic, NULL);
2830 
2831         leAudioDevice->src_pacs_.push_back(std::make_tuple(
2832             hdl_pair,
2833             std::vector<struct bluetooth::le_audio::types::acs_ac_record>()));
2834 
2835         log::info(
2836             "Found Source PAC characteristic, handle: 0x{:04x}, ccc handle: "
2837             "0x{:04x}, addr: {}",
2838             charac.value_handle, hdl_pair.ccc_hdl, leAudioDevice->address_);
2839       } else if (charac.uuid == bluetooth::le_audio::uuid::
2840                                     kSinkAudioLocationCharacteristicUuid) {
2841         leAudioDevice->snk_audio_locations_hdls_.val_hdl = charac.value_handle;
2842         leAudioDevice->snk_audio_locations_hdls_.ccc_hdl =
2843             find_ccc_handle(charac);
2844 
2845         if (leAudioDevice->snk_audio_locations_hdls_.ccc_hdl == 0) {
2846           log::info(", snk audio locations char doesn't have ccc");
2847         }
2848 
2849         if (leAudioDevice->snk_audio_locations_hdls_.ccc_hdl != 0 &&
2850             !subscribe_for_notification(
2851                 conn_id, leAudioDevice->address_,
2852                 leAudioDevice->snk_audio_locations_hdls_)) {
2853           disconnectInvalidDevice(
2854               leAudioDevice, ", could not subscribe for snk locations char",
2855               LeAudioHealthDeviceStatType::INVALID_DB);
2856           return;
2857         }
2858 
2859         /* Obtain initial state of sink audio locations */
2860         BtaGattQueue::ReadCharacteristic(
2861             conn_id, leAudioDevice->snk_audio_locations_hdls_.val_hdl,
2862             OnGattReadRspStatic, NULL);
2863 
2864         log::info(
2865             "Found Sink audio locations characteristic, handle: 0x{:04x}, ccc "
2866             "handle: 0x{:04x}, addr: {}",
2867             charac.value_handle,
2868             leAudioDevice->snk_audio_locations_hdls_.ccc_hdl,
2869             leAudioDevice->address_);
2870       } else if (charac.uuid == bluetooth::le_audio::uuid::
2871                                     kSourceAudioLocationCharacteristicUuid) {
2872         leAudioDevice->src_audio_locations_hdls_.val_hdl = charac.value_handle;
2873         leAudioDevice->src_audio_locations_hdls_.ccc_hdl =
2874             find_ccc_handle(charac);
2875 
2876         if (leAudioDevice->src_audio_locations_hdls_.ccc_hdl == 0) {
2877           log::info(", src audio locations char doesn't have ccc");
2878         }
2879 
2880         if (leAudioDevice->src_audio_locations_hdls_.ccc_hdl != 0 &&
2881             !subscribe_for_notification(
2882                 conn_id, leAudioDevice->address_,
2883                 leAudioDevice->src_audio_locations_hdls_)) {
2884           disconnectInvalidDevice(
2885               leAudioDevice, ", could not subscribe for src locations char",
2886               LeAudioHealthDeviceStatType::INVALID_DB);
2887           return;
2888         }
2889 
2890         /* Obtain initial state of source audio locations */
2891         BtaGattQueue::ReadCharacteristic(
2892             conn_id, leAudioDevice->src_audio_locations_hdls_.val_hdl,
2893             OnGattReadRspStatic, NULL);
2894 
2895         log::info(
2896             "Found Source audio locations characteristic, handle: 0x{:04x}, "
2897             "ccc handle: 0x{:04x}, addr: {}",
2898             charac.value_handle,
2899             leAudioDevice->src_audio_locations_hdls_.ccc_hdl,
2900             leAudioDevice->address_);
2901       } else if (charac.uuid ==
2902                  bluetooth::le_audio::uuid::
2903                      kAudioContextAvailabilityCharacteristicUuid) {
2904         leAudioDevice->audio_avail_hdls_.val_hdl = charac.value_handle;
2905         leAudioDevice->audio_avail_hdls_.ccc_hdl = find_ccc_handle(charac);
2906 
2907         if (leAudioDevice->audio_avail_hdls_.ccc_hdl == 0) {
2908           disconnectInvalidDevice(leAudioDevice,
2909                                   ", audio avails char doesn't have ccc",
2910                                   LeAudioHealthDeviceStatType::INVALID_DB);
2911           return;
2912         }
2913 
2914         if (!subscribe_for_notification(conn_id, leAudioDevice->address_,
2915                                         leAudioDevice->audio_avail_hdls_)) {
2916           disconnectInvalidDevice(leAudioDevice,
2917                                   ", could not subscribe for audio avails char",
2918                                   LeAudioHealthDeviceStatType::INVALID_DB);
2919           return;
2920         }
2921 
2922         /* Obtain initial state */
2923         BtaGattQueue::ReadCharacteristic(
2924             conn_id, leAudioDevice->audio_avail_hdls_.val_hdl,
2925             OnGattReadRspStatic, NULL);
2926 
2927         log::info(
2928             "Found Audio Availability Context characteristic, handle: "
2929             "0x{:04x}, ccc handle: 0x{:04x}, addr: {}",
2930             charac.value_handle, leAudioDevice->audio_avail_hdls_.ccc_hdl,
2931             leAudioDevice->address_);
2932       } else if (charac.uuid == bluetooth::le_audio::uuid::
2933                                     kAudioSupportedContextCharacteristicUuid) {
2934         leAudioDevice->audio_supp_cont_hdls_.val_hdl = charac.value_handle;
2935         leAudioDevice->audio_supp_cont_hdls_.ccc_hdl = find_ccc_handle(charac);
2936 
2937         if (leAudioDevice->audio_supp_cont_hdls_.ccc_hdl == 0) {
2938           log::info(", audio supported char doesn't have ccc");
2939         }
2940 
2941         if (leAudioDevice->audio_supp_cont_hdls_.ccc_hdl != 0 &&
2942             !subscribe_for_notification(conn_id, leAudioDevice->address_,
2943                                         leAudioDevice->audio_supp_cont_hdls_)) {
2944           disconnectInvalidDevice(
2945               leAudioDevice,
2946               ", could not subscribe for audio supported ctx char",
2947               LeAudioHealthDeviceStatType::INVALID_DB);
2948           return;
2949         }
2950 
2951         /* Obtain initial state */
2952         BtaGattQueue::ReadCharacteristic(
2953             conn_id, leAudioDevice->audio_supp_cont_hdls_.val_hdl,
2954             OnGattReadRspStatic, NULL);
2955 
2956         log::info(
2957             "Found Audio Supported Context characteristic, handle: 0x{:04x}, "
2958             "ccc handle: 0x{:04x}, addr: {}",
2959             charac.value_handle, leAudioDevice->audio_supp_cont_hdls_.ccc_hdl,
2960             leAudioDevice->address_);
2961       }
2962     }
2963 
2964     /* Refresh ASE handles */
2965     leAudioDevice->ases_.clear();
2966 
2967     for (const gatt::Characteristic& charac : ase_svc->characteristics) {
2968       log::info("Found characteristic, uuid: {}", charac.uuid.ToString());
2969       if (charac.uuid ==
2970               bluetooth::le_audio::uuid::kSinkAudioStreamEndpointUuid ||
2971           charac.uuid ==
2972               bluetooth::le_audio::uuid::kSourceAudioStreamEndpointUuid) {
2973         uint16_t ccc_handle = find_ccc_handle(charac);
2974         if (ccc_handle == 0) {
2975           disconnectInvalidDevice(leAudioDevice, ", ASE char doesn't have ccc",
2976                                   LeAudioHealthDeviceStatType::INVALID_DB);
2977           return;
2978         }
2979         struct bluetooth::le_audio::types::hdl_pair hdls(charac.value_handle,
2980                                                          ccc_handle);
2981         if (!subscribe_for_notification(conn_id, leAudioDevice->address_,
2982                                         hdls)) {
2983           disconnectInvalidDevice(leAudioDevice,
2984                                   ", could not subscribe ASE char",
2985                                   LeAudioHealthDeviceStatType::INVALID_DB);
2986           return;
2987         }
2988 
2989         int direction =
2990             charac.uuid ==
2991                     bluetooth::le_audio::uuid::kSinkAudioStreamEndpointUuid
2992                 ? bluetooth::le_audio::types::kLeAudioDirectionSink
2993                 : bluetooth::le_audio::types::kLeAudioDirectionSource;
2994 
2995         leAudioDevice->ases_.emplace_back(charac.value_handle, ccc_handle,
2996                                           direction);
2997 
2998         log::info(
2999             "Found ASE characteristic, handle: 0x{:04x}, ccc handle: 0x{:04x}, "
3000             "direction: {}, addr: {}",
3001             charac.value_handle, ccc_handle, direction,
3002             leAudioDevice->address_);
3003       } else if (charac.uuid ==
3004                  bluetooth::le_audio::uuid::
3005                      kAudioStreamEndpointControlPointCharacteristicUuid) {
3006         leAudioDevice->ctp_hdls_.val_hdl = charac.value_handle;
3007         leAudioDevice->ctp_hdls_.ccc_hdl = find_ccc_handle(charac);
3008 
3009         if (leAudioDevice->ctp_hdls_.ccc_hdl == 0) {
3010           disconnectInvalidDevice(leAudioDevice, ", ASE ctp doesn't have ccc",
3011                                   LeAudioHealthDeviceStatType::INVALID_DB);
3012           return;
3013         }
3014 
3015         if (!subscribe_for_notification(conn_id, leAudioDevice->address_,
3016                                         leAudioDevice->ctp_hdls_)) {
3017           disconnectInvalidDevice(leAudioDevice,
3018                                   ", could not subscribe ASE char",
3019                                   LeAudioHealthDeviceStatType::INVALID_DB);
3020           return;
3021         }
3022 
3023         log::info(
3024             "Found ASE Control Point characteristic, handle: 0x{:04x}, ccc "
3025             "handle: 0x{:04x}, addr: {}",
3026             charac.value_handle, leAudioDevice->ctp_hdls_.ccc_hdl,
3027             leAudioDevice->address_);
3028       }
3029     }
3030 
3031     if (tmas_svc) {
3032       for (const gatt::Characteristic& charac : tmas_svc->characteristics) {
3033         if (charac.uuid ==
3034             bluetooth::le_audio::uuid::
3035                 kTelephonyMediaAudioProfileRoleCharacteristicUuid) {
3036           leAudioDevice->tmap_role_hdl_ = charac.value_handle;
3037 
3038           /* Obtain initial state of TMAP role */
3039           BtaGattQueue::ReadCharacteristic(conn_id,
3040                                            leAudioDevice->tmap_role_hdl_,
3041                                            OnGattReadRspStatic, NULL);
3042 
3043           log::info(
3044               "Found Telephony and Media Profile characteristic, handle: "
3045               "0x{:04x}, device: {}",
3046               leAudioDevice->tmap_role_hdl_, leAudioDevice->address_);
3047         }
3048       }
3049     }
3050 
3051     leAudioDevice->known_service_handles_ = true;
3052     leAudioDevice->notify_connected_after_read_ = true;
3053     if (leAudioHealthStatus_) {
3054       leAudioHealthStatus_->AddStatisticForDevice(
3055           leAudioDevice, LeAudioHealthDeviceStatType::VALID_DB);
3056     }
3057 
3058     /* If already known group id */
3059     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
3060       AseInitialStateReadRequest(leAudioDevice);
3061       return;
3062     }
3063 
3064     /* If device does not belong to any group yet we either add it to the
3065      * group by our selfs now or wait for Csis to do it. In both cases, let's
3066      * check if group is already assigned.
3067      */
3068     int group_id = DeviceGroups::Get()->GetGroupId(
3069         leAudioDevice->address_, bluetooth::le_audio::uuid::kCapServiceUuid);
3070     if (group_id != bluetooth::groups::kGroupUnknown) {
3071       instance->group_add_node(group_id, leAudioDevice->address_);
3072       return;
3073     }
3074 
3075     /* CSIS will trigger adding to group */
3076     if (leAudioDevice->csis_member_) {
3077       log::info("{},  waiting for CSIS to create group for device",
3078                 leAudioDevice->address_);
3079       scheduleGuardForCsisAdd(leAudioDevice->address_);
3080       return;
3081     }
3082 
3083     log::info("{} Not a CSIS member. Create group by our own",
3084               leAudioDevice->address_);
3085 
3086     /* If there is no Csis just add device by our own */
3087     DeviceGroups::Get()->AddDevice(leAudioDevice->address_,
3088                                    bluetooth::le_audio::uuid::kCapServiceUuid);
3089   }
3090 
OnGattWriteCcc(uint16_t conn_id,tGATT_STATUS status,uint16_t hdl,void * data)3091   void OnGattWriteCcc(uint16_t conn_id, tGATT_STATUS status, uint16_t hdl,
3092                       void* data) {
3093     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
3094     std::vector<struct ase>::iterator ase_it;
3095 
3096     if (!leAudioDevice) {
3097       log::error("unknown conn_id=0x{:x}", conn_id);
3098       return;
3099     }
3100 
3101     if (status == GATT_DATABASE_OUT_OF_SYNC) {
3102       log::info("Database out of sync for {}, conn_id: 0x{:04x}",
3103                 leAudioDevice->address_, conn_id);
3104       ClearDeviceInformationAndStartSearch(leAudioDevice);
3105       return;
3106     }
3107 
3108     if (status == GATT_SUCCESS) {
3109       log::info("Successfully registered on ccc: 0x{:04x}, device: {}", hdl,
3110                 leAudioDevice->address_);
3111 
3112       if (leAudioDevice->ctp_hdls_.ccc_hdl == hdl &&
3113           leAudioDevice->known_service_handles_ &&
3114           !leAudioDevice->notify_connected_after_read_) {
3115         /* Reconnection case. Control point is the last CCC LeAudio is
3116          * registering for on reconnection */
3117         connectionReady(leAudioDevice);
3118       }
3119 
3120       return;
3121     }
3122 
3123     log::error(
3124         "Failed to register for notifications: 0x{:04x}, device: {}, status: "
3125         "0x{:02x}",
3126         hdl, leAudioDevice->address_, status);
3127 
3128     ase_it =
3129         std::find_if(leAudioDevice->ases_.begin(), leAudioDevice->ases_.end(),
3130                      [&hdl](const struct ase& ase) -> bool {
3131                        return ase.hdls.ccc_hdl == hdl;
3132                      });
3133 
3134     if (ase_it == leAudioDevice->ases_.end()) {
3135       log::error("Unknown ccc handle: 0x{:04x}, device: {}", hdl,
3136                  leAudioDevice->address_);
3137       return;
3138     }
3139 
3140     BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
3141                                          ase_it->hdls.val_hdl);
3142   }
3143 
AttachToStreamingGroupIfNeeded(LeAudioDevice * leAudioDevice)3144   void AttachToStreamingGroupIfNeeded(LeAudioDevice* leAudioDevice) {
3145     if (leAudioDevice->group_id_ != active_group_id_) {
3146       log::info("group  {} is not streaming. Nothing to do",
3147                 leAudioDevice->group_id_);
3148       return;
3149     }
3150 
3151     if (leAudioDevice->HaveActiveAse()) {
3152       log::debug("{} is already configured, nothing to do",
3153                  leAudioDevice->address_);
3154       return;
3155     }
3156 
3157     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
3158 
3159     auto group_metadata_contexts =
3160         get_bidirectional(group->GetMetadataContexts());
3161     auto device_available_contexts = leAudioDevice->GetAvailableContexts();
3162     if (!group_metadata_contexts.test_any(device_available_contexts)) {
3163       log::info("{} does is not have required context type",
3164                 leAudioDevice->address_);
3165       return;
3166     }
3167 
3168     /* Restore configuration */
3169     auto* stream_conf = &group->stream_conf;
3170 
3171     if (audio_sender_state_ == AudioState::IDLE &&
3172         audio_receiver_state_ == AudioState::IDLE) {
3173       log::debug("Device not streaming but active - nothing to do");
3174       return;
3175     }
3176 
3177     if (!stream_conf->conf) {
3178       log::info("Configuration not yet set. Nothing to do now");
3179       return;
3180     }
3181 
3182     log::info("Attaching {} to group: {}", leAudioDevice->address_,
3183               leAudioDevice->group_id_);
3184 
3185     for (auto direction :
3186          {bluetooth::le_audio::types::kLeAudioDirectionSink,
3187           bluetooth::le_audio::types::kLeAudioDirectionSource}) {
3188       log::info("Looking for requirements: {} - {}", stream_conf->conf->name,
3189                 ((direction == 1 ? "snk" : "src")));
3190       const auto& pacs =
3191           (direction == bluetooth::le_audio::types::kLeAudioDirectionSink)
3192               ? leAudioDevice->snk_pacs_
3193               : leAudioDevice->src_pacs_;
3194       for (const auto& ent : stream_conf->conf->confs.get(direction)) {
3195         if (!bluetooth::le_audio::utils::GetConfigurationSupportedPac(
3196                 pacs, ent.codec)) {
3197           log::info("Configuration is not supported by device {}",
3198                     leAudioDevice->address_);
3199 
3200           /* Reconfigure if newly connected member device cannot support
3201            * current codec configuration */
3202           group->SetPendingConfiguration();
3203           groupStateMachine_->StopStream(group);
3204           stream_setup_start_timestamp_ =
3205               bluetooth::common::time_get_os_boottime_us();
3206           return;
3207         }
3208       }
3209     }
3210 
3211     /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */
3212     auto ccid_contexts = group->GetMetadataContexts();
3213     if (IsInVoipCall() && !IsInCall()) {
3214       ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL);
3215       ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL);
3216     }
3217     BidirectionalPair<std::vector<uint8_t>> ccids = {
3218         .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids(
3219             ccid_contexts.sink),
3220         .source = ContentControlIdKeeper::GetInstance()->GetAllCcids(
3221             ccid_contexts.source)};
3222 
3223     if (!groupStateMachine_->AttachToStream(group, leAudioDevice,
3224                                             std::move(ccids))) {
3225       log::warn("Could not add device {} to the group {} streaming.",
3226                 leAudioDevice->address_, group->group_id_);
3227       scheduleAttachDeviceToTheStream(leAudioDevice->address_);
3228     } else {
3229       stream_setup_start_timestamp_ =
3230           bluetooth::common::time_get_os_boottime_us();
3231     }
3232   }
3233 
restartAttachToTheStream(const RawAddress & addr)3234   void restartAttachToTheStream(const RawAddress& addr) {
3235     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
3236     if (leAudioDevice == nullptr ||
3237         leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID) {
3238       log::info("Device {} not available anymore", addr);
3239       return;
3240     }
3241     AttachToStreamingGroupIfNeeded(leAudioDevice);
3242   }
3243 
scheduleAttachDeviceToTheStream(const RawAddress & addr)3244   void scheduleAttachDeviceToTheStream(const RawAddress& addr) {
3245     log::info("Device {} scheduler for stream", addr);
3246     do_in_main_thread_delayed(
3247         FROM_HERE,
3248         base::BindOnce(&LeAudioClientImpl::restartAttachToTheStream,
3249                        weak_factory_.GetWeakPtr(), addr),
3250         std::chrono::milliseconds(kDeviceAttachDelayMs));
3251   }
3252 
SendAudioGroupSelectableCodecConfigChanged(LeAudioDeviceGroup * group)3253   void SendAudioGroupSelectableCodecConfigChanged(LeAudioDeviceGroup* group) {
3254     auto leAudioDevice = group->GetFirstDevice();
3255     callbacks_->OnAudioGroupSelectableCodecConf(
3256         group->group_id_,
3257         bluetooth::le_audio::utils::GetRemoteBtLeAudioCodecConfigFromPac(
3258             leAudioDevice->src_pacs_),
3259         bluetooth::le_audio::utils::GetRemoteBtLeAudioCodecConfigFromPac(
3260             leAudioDevice->snk_pacs_));
3261   }
3262 
SendAudioGroupCurrentCodecConfigChanged(LeAudioDeviceGroup * group)3263   void SendAudioGroupCurrentCodecConfigChanged(LeAudioDeviceGroup* group) {
3264     // This shall be called when configuration changes
3265     log::debug("{}", group->group_id_);
3266 
3267     auto audio_set_conf = group->GetConfiguration(configuration_context_type_);
3268     if (!audio_set_conf) {
3269       log::warn("Stream configuration is not valid for group id {}",
3270                 group->group_id_);
3271       return;
3272     }
3273 
3274     bluetooth::le_audio::btle_audio_codec_config_t input_config{};
3275     bluetooth::le_audio::utils::fillStreamParamsToBtLeAudioCodecConfig(
3276         audio_set_conf->confs.source, input_config);
3277 
3278     bluetooth::le_audio::btle_audio_codec_config_t output_config{};
3279     bluetooth::le_audio::utils::fillStreamParamsToBtLeAudioCodecConfig(
3280         audio_set_conf->confs.sink, output_config);
3281 
3282     callbacks_->OnAudioGroupCurrentCodecConf(group->group_id_, input_config,
3283                                              output_config);
3284   }
3285 
connectionReady(LeAudioDevice * leAudioDevice)3286   void connectionReady(LeAudioDevice* leAudioDevice) {
3287     log::debug(
3288         "{},  {}", leAudioDevice->address_,
3289         bluetooth::common::ToString(leAudioDevice->GetConnectionState()));
3290 
3291     L2CA_LockBleConnParamsForProfileConnection(leAudioDevice->address_, false);
3292 
3293     if (leAudioDevice->GetConnectionState() ==
3294             DeviceConnectState::CONNECTED_BY_USER_GETTING_READY &&
3295         (leAudioDevice->autoconnect_flag_ == false)) {
3296       btif_storage_set_leaudio_autoconnect(leAudioDevice->address_, true);
3297       leAudioDevice->autoconnect_flag_ = true;
3298     }
3299 
3300     leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED);
3301     bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
3302         leAudioDevice->group_id_, leAudioDevice->address_,
3303         ConnectionState::CONNECTED,
3304         bluetooth::le_audio::ConnectionStatus::SUCCESS);
3305 
3306     if (leAudioDevice->group_id_ == bluetooth::groups::kGroupUnknown) {
3307       log::warn("LeAudio device {} connected with no group",
3308                 leAudioDevice->address_);
3309       callbacks_->OnConnectionState(ConnectionState::CONNECTED,
3310                                     leAudioDevice->address_);
3311       return;
3312     }
3313 
3314     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
3315     if (group) {
3316       UpdateLocationsAndContextsAvailability(group, true);
3317     }
3318 
3319     /* Notify connected after contexts are notified */
3320     callbacks_->OnConnectionState(ConnectionState::CONNECTED,
3321                                   leAudioDevice->address_);
3322 
3323     AttachToStreamingGroupIfNeeded(leAudioDevice);
3324 
3325     if (reconnection_mode_ == BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS) {
3326       /* Add other devices to allow list if there are any not yet connected
3327        * from the group
3328        */
3329       group->AddToAllowListNotConnectedGroupMembers(gatt_if_);
3330     }
3331   }
3332 
IsAseAcceptingAudioData(struct ase * ase)3333   bool IsAseAcceptingAudioData(struct ase* ase) {
3334     if (ase == nullptr) return false;
3335     if (ase->state != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) return false;
3336     if (ase->data_path_state != DataPathState::CONFIGURED) return false;
3337 
3338     return true;
3339   }
3340 
3341   // mix stero signal into mono
mono_blend(const std::vector<uint8_t> & buf,int bytes_per_sample,size_t frames)3342   std::vector<uint8_t> mono_blend(const std::vector<uint8_t>& buf,
3343                                   int bytes_per_sample, size_t frames) {
3344     std::vector<uint8_t> mono_out;
3345     mono_out.resize(frames * bytes_per_sample);
3346 
3347     if (bytes_per_sample == 2) {
3348       int16_t* out = (int16_t*)mono_out.data();
3349       const int16_t* in = (int16_t*)(buf.data());
3350       for (size_t i = 0; i < frames; ++i) {
3351         int accum = 0;
3352         accum += *in++;
3353         accum += *in++;
3354         accum /= 2;  // round to 0
3355         *out++ = accum;
3356       }
3357     } else if (bytes_per_sample == 4) {
3358       int32_t* out = (int32_t*)mono_out.data();
3359       const int32_t* in = (int32_t*)(buf.data());
3360       for (size_t i = 0; i < frames; ++i) {
3361         int accum = 0;
3362         accum += *in++;
3363         accum += *in++;
3364         accum /= 2;  // round to 0
3365         *out++ = accum;
3366       }
3367     } else {
3368       log::error("Don't know how to mono blend that {}!", bytes_per_sample);
3369     }
3370     return mono_out;
3371   }
3372 
PrepareAndSendToTwoCises(const std::vector<uint8_t> & data,const struct bluetooth::le_audio::stream_parameters & stream_params)3373   void PrepareAndSendToTwoCises(
3374       const std::vector<uint8_t>& data,
3375       const struct bluetooth::le_audio::stream_parameters& stream_params) {
3376     uint16_t left_cis_handle = 0;
3377     uint16_t right_cis_handle = 0;
3378 
3379     uint16_t number_of_required_samples_per_channel =
3380         sw_enc_left->GetNumOfSamplesPerChannel();
3381     uint8_t bytes_per_sample = sw_enc_left->GetNumOfBytesPerSample();
3382     if (data.size() < bytes_per_sample * 2 /* channels */ *
3383                           number_of_required_samples_per_channel) {
3384       log::error("Missing samples. Data size: {} expected: {}", data.size(),
3385                  bytes_per_sample * 2 * number_of_required_samples_per_channel);
3386       return;
3387     }
3388 
3389     for (auto [cis_handle, audio_location] : stream_params.stream_locations) {
3390       if (audio_location &
3391           bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyLeft)
3392         left_cis_handle = cis_handle;
3393       if (audio_location &
3394           bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyRight)
3395         right_cis_handle = cis_handle;
3396     }
3397 
3398     uint16_t byte_count = stream_params.octets_per_codec_frame;
3399     bool mix_to_mono = (left_cis_handle == 0) || (right_cis_handle == 0);
3400     if (mix_to_mono) {
3401       std::vector<uint8_t> mono = mono_blend(
3402           data, bytes_per_sample, number_of_required_samples_per_channel);
3403       if (left_cis_handle) {
3404         sw_enc_left->Encode(mono.data(), 1, byte_count);
3405       }
3406 
3407       if (right_cis_handle) {
3408         sw_enc_left->Encode(mono.data(), 1, byte_count);
3409       }
3410     } else {
3411       sw_enc_left->Encode(data.data(), 2, byte_count);
3412       sw_enc_right->Encode(data.data() + bytes_per_sample, 2, byte_count);
3413     }
3414 
3415     log::debug("left_cis_handle: {} right_cis_handle: {}", left_cis_handle,
3416                right_cis_handle);
3417     /* Send data to the controller */
3418     if (left_cis_handle)
3419       IsoManager::GetInstance()->SendIsoData(
3420           left_cis_handle,
3421           (const uint8_t*)sw_enc_left->GetDecodedSamples().data(),
3422           sw_enc_left->GetDecodedSamples().size() * 2);
3423 
3424     if (right_cis_handle)
3425       IsoManager::GetInstance()->SendIsoData(
3426           right_cis_handle,
3427           (const uint8_t*)sw_enc_right->GetDecodedSamples().data(),
3428           sw_enc_right->GetDecodedSamples().size() * 2);
3429   }
3430 
PrepareAndSendToSingleCis(const std::vector<uint8_t> & data,const struct bluetooth::le_audio::stream_parameters & stream_params)3431   void PrepareAndSendToSingleCis(
3432       const std::vector<uint8_t>& data,
3433       const struct bluetooth::le_audio::stream_parameters& stream_params) {
3434     uint16_t num_channels = stream_params.num_of_channels;
3435     uint16_t cis_handle = stream_params.stream_locations.front().first;
3436 
3437     uint16_t number_of_required_samples_per_channel =
3438         sw_enc_left->GetNumOfSamplesPerChannel();
3439     uint8_t bytes_per_sample = sw_enc_left->GetNumOfBytesPerSample();
3440     if ((int)data.size() < (bytes_per_sample * num_channels *
3441                             number_of_required_samples_per_channel)) {
3442       log::error("Missing samples");
3443       return;
3444     }
3445 
3446     uint16_t byte_count = stream_params.octets_per_codec_frame;
3447     bool mix_to_mono = (num_channels == 1);
3448     if (mix_to_mono) {
3449       /* Since we always get two channels from framework, lets make it mono here
3450        */
3451       std::vector<uint8_t> mono = mono_blend(
3452           data, bytes_per_sample, number_of_required_samples_per_channel);
3453       sw_enc_left->Encode(mono.data(), 1, byte_count);
3454     } else {
3455       sw_enc_left->Encode((const uint8_t*)data.data(), 2, byte_count);
3456       // Output to the left channel buffer with `byte_count` offset
3457       sw_enc_right->Encode((const uint8_t*)data.data() + 2, 2, byte_count,
3458                            &sw_enc_left->GetDecodedSamples(), byte_count);
3459     }
3460 
3461     IsoManager::GetInstance()->SendIsoData(
3462         cis_handle, (const uint8_t*)sw_enc_left->GetDecodedSamples().data(),
3463         sw_enc_left->GetDecodedSamples().size() * 2);
3464   }
3465 
3466   const struct bluetooth::le_audio::stream_configuration*
GetStreamSinkConfiguration(LeAudioDeviceGroup * group)3467   GetStreamSinkConfiguration(LeAudioDeviceGroup* group) {
3468     const struct bluetooth::le_audio::stream_configuration* stream_conf =
3469         &group->stream_conf;
3470     log::info("group_id: {}", group->group_id_);
3471     if (stream_conf->stream_params.sink.stream_locations.size() == 0) {
3472       return nullptr;
3473     }
3474 
3475     log::info("configuration: {}", stream_conf->conf->name);
3476     return stream_conf;
3477   }
3478 
OnAudioDataReady(const std::vector<uint8_t> & data)3479   void OnAudioDataReady(const std::vector<uint8_t>& data) {
3480     if ((active_group_id_ == bluetooth::groups::kGroupUnknown) ||
3481         (audio_sender_state_ != AudioState::STARTED))
3482       return;
3483 
3484     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
3485     if (!group) {
3486       log::error("There is no streaming group available");
3487       return;
3488     }
3489 
3490     auto stream_conf = group->stream_conf;
3491     if ((stream_conf.stream_params.sink.num_of_devices > 2) ||
3492         (stream_conf.stream_params.sink.num_of_devices == 0) ||
3493         stream_conf.stream_params.sink.stream_locations.empty()) {
3494       log::error("Stream configufation is not valid.");
3495       return;
3496     }
3497 
3498     if ((stream_conf.stream_params.sink.num_of_devices == 2) ||
3499         (stream_conf.stream_params.sink.stream_locations.size() == 2)) {
3500       /* Streaming to two devices or one device with 2 CISes */
3501       PrepareAndSendToTwoCises(data, stream_conf.stream_params.sink);
3502     } else {
3503       /* Streaming to one device and 1 CIS */
3504       PrepareAndSendToSingleCis(data, stream_conf.stream_params.sink);
3505     }
3506   }
3507 
CleanCachedMicrophoneData()3508   void CleanCachedMicrophoneData() {
3509     cached_channel_timestamp_ = 0;
3510     cached_channel_ = nullptr;
3511   }
3512 
3513   /* Handles audio data packets coming from the controller */
HandleIncomingCisData(uint8_t * data,uint16_t size,uint16_t cis_conn_hdl,uint32_t timestamp)3514   void HandleIncomingCisData(uint8_t* data, uint16_t size,
3515                              uint16_t cis_conn_hdl, uint32_t timestamp) {
3516     /* Get only one channel for MONO microphone */
3517     /* Gather data for channel */
3518     if ((active_group_id_ == bluetooth::groups::kGroupUnknown) ||
3519         (audio_receiver_state_ != AudioState::STARTED))
3520       return;
3521 
3522     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
3523     if (!group) {
3524       log::error("There is no streaming group available");
3525       return;
3526     }
3527 
3528     uint16_t left_cis_handle = 0;
3529     uint16_t right_cis_handle = 0;
3530     for (auto [cis_handle, audio_location] :
3531          group->stream_conf.stream_params.source.stream_locations) {
3532       if (audio_location &
3533           bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyLeft) {
3534         left_cis_handle = cis_handle;
3535       }
3536       if (audio_location &
3537           bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyRight) {
3538         right_cis_handle = cis_handle;
3539       }
3540     }
3541 
3542     auto decoder = sw_dec_left.get();
3543     if (cis_conn_hdl == left_cis_handle) {
3544       decoder = sw_dec_left.get();
3545     } else if (cis_conn_hdl == right_cis_handle) {
3546       decoder = sw_dec_right.get();
3547     } else {
3548       log::error("Received data for unknown handle: {:04x}", cis_conn_hdl);
3549       return;
3550     }
3551 
3552     if (!left_cis_handle || !right_cis_handle) {
3553       /* mono or just one device connected */
3554       decoder->Decode(data, size);
3555       SendAudioDataToAF(&decoder->GetDecodedSamples());
3556       return;
3557     }
3558     /* both devices are connected */
3559 
3560     if (cached_channel_ == nullptr ||
3561         cached_channel_->GetDecodedSamples().empty()) {
3562       /* First packet received, cache it. We need both channel data to send it
3563        * to AF. */
3564       decoder->Decode(data, size);
3565       cached_channel_timestamp_ = timestamp;
3566       cached_channel_ = decoder;
3567       return;
3568     }
3569 
3570     /* We received either data for the other audio channel, or another
3571      * packet for same channel */
3572     if (cached_channel_ != decoder) {
3573       /* It's data for the 2nd channel */
3574       if (timestamp == cached_channel_timestamp_) {
3575         /* Ready to mix data and send out to AF */
3576         decoder->Decode(data, size);
3577         SendAudioDataToAF(&sw_dec_left->GetDecodedSamples(),
3578                           &sw_dec_right->GetDecodedSamples());
3579 
3580         CleanCachedMicrophoneData();
3581         return;
3582       }
3583 
3584       /* 2nd Channel is in the future compared to the cached data.
3585        Send the cached data to AF, and keep the new channel data in cache.
3586        This should happen only during stream setup */
3587       SendAudioDataToAF(&decoder->GetDecodedSamples());
3588 
3589       decoder->Decode(data, size);
3590       cached_channel_timestamp_ = timestamp;
3591       cached_channel_ = decoder;
3592       return;
3593     }
3594 
3595     /* Data for same channel received. 2nd channel is down/not sending
3596      * data */
3597 
3598     /* Send the cached data out */
3599     SendAudioDataToAF(&decoder->GetDecodedSamples());
3600 
3601     /* Cache the data in case 2nd channel connects */
3602     decoder->Decode(data, size);
3603     cached_channel_timestamp_ = timestamp;
3604     cached_channel_ = decoder;
3605   }
3606 
SendAudioDataToAF(std::vector<int16_t> * left,std::vector<int16_t> * right=nullptr)3607   void SendAudioDataToAF(std::vector<int16_t>* left,
3608                          std::vector<int16_t>* right = nullptr) {
3609     uint16_t to_write = 0;
3610     uint16_t written = 0;
3611 
3612     bool af_is_stereo = (audio_framework_sink_config.num_channels == 2);
3613     bool bt_got_stereo = (left != nullptr) & (right != nullptr);
3614 
3615     if (!af_is_stereo) {
3616       if (!bt_got_stereo) {
3617         std::vector<int16_t>* mono = left ? left : right;
3618         /* mono audio over bluetooth, audio framework expects mono */
3619         to_write = sizeof(int16_t) * mono->size();
3620         written = le_audio_sink_hal_client_->SendData((uint8_t*)mono->data(),
3621                                                       to_write);
3622       } else {
3623         /* stereo audio over bluetooth, audio framework expects mono */
3624         for (size_t i = 0; i < left->size(); i++) {
3625           (*left)[i] = ((*left)[i] + (*right)[i]) / 2;
3626         }
3627         to_write = sizeof(int16_t) * left->size();
3628         written = le_audio_sink_hal_client_->SendData((uint8_t*)left->data(),
3629                                                       to_write);
3630       }
3631     } else {
3632       /* mono audio over bluetooth, audio framework expects stereo
3633        * Here we handle stream without checking bt_got_stereo flag.
3634        */
3635       const size_t mono_size = left ? left->size() : right->size();
3636       std::vector<uint16_t> mixed(mono_size * 2);
3637 
3638       for (size_t i = 0; i < mono_size; i++) {
3639         mixed[2 * i] = left ? (*left)[i] : (*right)[i];
3640         mixed[2 * i + 1] = right ? (*right)[i] : (*left)[i];
3641       }
3642       to_write = sizeof(int16_t) * mixed.size();
3643       written =
3644           le_audio_sink_hal_client_->SendData((uint8_t*)mixed.data(), to_write);
3645     }
3646 
3647     /* TODO: What to do if not all data sinked ? */
3648     if (written != to_write) log::error("not all data sinked");
3649   }
3650 
ConfirmLocalAudioSourceStreamingRequest()3651   void ConfirmLocalAudioSourceStreamingRequest() {
3652     le_audio_source_hal_client_->ConfirmStreamingRequest();
3653 
3654     LeAudioLogHistory::Get()->AddLogHistory(
3655         kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
3656         kLogAfResumeConfirm + "LocalSource",
3657         "s_state: " + ToString(audio_sender_state_) + "-> STARTED");
3658 
3659     audio_sender_state_ = AudioState::STARTED;
3660   }
3661 
ConfirmLocalAudioSinkStreamingRequest()3662   void ConfirmLocalAudioSinkStreamingRequest() {
3663     le_audio_sink_hal_client_->ConfirmStreamingRequest();
3664 
3665     LeAudioLogHistory::Get()->AddLogHistory(
3666         kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
3667         kLogAfResumeConfirm + "LocalSink",
3668         "r_state: " + ToString(audio_receiver_state_) + "-> STARTED");
3669 
3670     audio_receiver_state_ = AudioState::STARTED;
3671   }
3672 
StartSendingAudio(int group_id)3673   void StartSendingAudio(int group_id) {
3674     log::info("");
3675 
3676     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
3677     LeAudioDevice* device = group->GetFirstActiveDevice();
3678     log::assert_that(device, "Shouldn't be called without an active device.");
3679 
3680     /* Assume 2 ases max just for now. */
3681     auto* stream_conf = GetStreamSinkConfiguration(group);
3682     if (stream_conf == nullptr) {
3683       log::error("could not get sink configuration");
3684       groupStateMachine_->StopStream(group);
3685       return;
3686     }
3687 
3688     log::debug("Sink stream config (#{}):\n",
3689                static_cast<int>(
3690                    stream_conf->stream_params.sink.stream_locations.size()));
3691     for (auto stream : stream_conf->stream_params.sink.stream_locations) {
3692       log::debug("Cis handle: 0x{:02x}, allocation 0x{:04x}\n", stream.first,
3693                  stream.second);
3694     }
3695     log::debug("Source stream config (#{}):\n",
3696                static_cast<int>(
3697                    stream_conf->stream_params.source.stream_locations.size()));
3698     for (auto stream : stream_conf->stream_params.source.stream_locations) {
3699       log::debug("Cis handle: 0x{:02x}, allocation 0x{:04x}\n", stream.first,
3700                  stream.second);
3701     }
3702 
3703     uint16_t remote_delay_ms = group->GetRemoteDelay(
3704         bluetooth::le_audio::types::kLeAudioDirectionSink);
3705     if (CodecManager::GetInstance()->GetCodecLocation() ==
3706         bluetooth::le_audio::types::CodecLocation::HOST) {
3707       if (sw_enc_left || sw_enc_right) {
3708         log::warn("The encoder instance should have been already released.");
3709       }
3710       sw_enc_left = bluetooth::le_audio::CodecInterface::CreateInstance(
3711           stream_conf->codec_id);
3712       auto codec_status = sw_enc_left->InitEncoder(
3713           audio_framework_source_config, current_encoder_config_);
3714       if (codec_status !=
3715           bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
3716         log::error("Left channel codec setup failed with err: {}",
3717                    codec_status);
3718         groupStateMachine_->StopStream(group);
3719         return;
3720       }
3721 
3722       sw_enc_right = bluetooth::le_audio::CodecInterface::CreateInstance(
3723           stream_conf->codec_id);
3724       codec_status = sw_enc_right->InitEncoder(audio_framework_source_config,
3725                                                current_encoder_config_);
3726       if (codec_status !=
3727           bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
3728         log::error("Right channel codec setup failed with err: {}",
3729                    codec_status);
3730         groupStateMachine_->StopStream(group);
3731         return;
3732       }
3733     }
3734 
3735     le_audio_source_hal_client_->UpdateRemoteDelay(remote_delay_ms);
3736     ConfirmLocalAudioSourceStreamingRequest();
3737 
3738     if (!LeAudioHalVerifier::SupportsStreamActiveApi()) {
3739       /* We update the target audio allocation before streamStarted so that the
3740        * CodecManager would know how to configure the encoder. */
3741       BidirectionalPair<uint16_t> delays_pair = {
3742           .sink = group->GetRemoteDelay(
3743               bluetooth::le_audio::types::kLeAudioDirectionSink),
3744           .source = group->GetRemoteDelay(
3745               bluetooth::le_audio::types::kLeAudioDirectionSource)};
3746       CodecManager::GetInstance()->UpdateActiveAudioConfig(
3747           group->stream_conf.stream_params, delays_pair,
3748           std::bind(&LeAudioClientImpl::UpdateAudioConfigToHal,
3749                     weak_factory_.GetWeakPtr(), std::placeholders::_1,
3750                     std::placeholders::_2));
3751     }
3752   }
3753 
3754   const struct bluetooth::le_audio::stream_configuration*
GetStreamSourceConfiguration(LeAudioDeviceGroup * group)3755   GetStreamSourceConfiguration(LeAudioDeviceGroup* group) {
3756     const struct bluetooth::le_audio::stream_configuration* stream_conf =
3757         &group->stream_conf;
3758     if (stream_conf->stream_params.source.stream_locations.size() == 0) {
3759       return nullptr;
3760     }
3761     log::info("configuration: {}", stream_conf->conf->name);
3762     return stream_conf;
3763   }
3764 
StartReceivingAudio(int group_id)3765   void StartReceivingAudio(int group_id) {
3766     log::info("");
3767 
3768     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
3769 
3770     auto* stream_conf = GetStreamSourceConfiguration(group);
3771     if (!stream_conf) {
3772       log::warn(
3773           "Could not get source configuration for group {} probably microphone "
3774           "not configured",
3775           active_group_id_);
3776       groupStateMachine_->StopStream(group);
3777       return;
3778     }
3779 
3780     uint16_t remote_delay_ms = group->GetRemoteDelay(
3781         bluetooth::le_audio::types::kLeAudioDirectionSource);
3782 
3783     CleanCachedMicrophoneData();
3784 
3785     if (CodecManager::GetInstance()->GetCodecLocation() ==
3786         bluetooth::le_audio::types::CodecLocation::HOST) {
3787       if (sw_dec_left.get() || sw_dec_right.get()) {
3788         log::warn("The decoder instance should have been already released.");
3789       }
3790       sw_dec_left = bluetooth::le_audio::CodecInterface::CreateInstance(
3791           stream_conf->codec_id);
3792       auto codec_status = sw_dec_left->InitDecoder(current_decoder_config_,
3793                                                    audio_framework_sink_config);
3794       if (codec_status !=
3795           bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
3796         log::error("Left channel codec setup failed with err: {}",
3797                    codec_status);
3798         groupStateMachine_->StopStream(group);
3799         return;
3800       }
3801 
3802       sw_dec_right = bluetooth::le_audio::CodecInterface::CreateInstance(
3803           stream_conf->codec_id);
3804       codec_status = sw_dec_right->InitDecoder(current_decoder_config_,
3805                                                audio_framework_sink_config);
3806       if (codec_status !=
3807           bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
3808         log::error("Right channel codec setup failed with err: {}",
3809                    codec_status);
3810         groupStateMachine_->StopStream(group);
3811         return;
3812       }
3813     }
3814     le_audio_sink_hal_client_->UpdateRemoteDelay(remote_delay_ms);
3815     ConfirmLocalAudioSinkStreamingRequest();
3816 
3817     if (!LeAudioHalVerifier::SupportsStreamActiveApi()) {
3818       /* We update the target audio allocation before streamStarted so that the
3819        * CodecManager would know how to configure the encoder. */
3820       BidirectionalPair<uint16_t> delays_pair = {
3821           .sink = group->GetRemoteDelay(
3822               bluetooth::le_audio::types::kLeAudioDirectionSink),
3823           .source = group->GetRemoteDelay(
3824               bluetooth::le_audio::types::kLeAudioDirectionSource)};
3825       CodecManager::GetInstance()->UpdateActiveAudioConfig(
3826           group->stream_conf.stream_params, delays_pair,
3827           std::bind(&LeAudioClientImpl::UpdateAudioConfigToHal,
3828                     weak_factory_.GetWeakPtr(), std::placeholders::_1,
3829                     std::placeholders::_2));
3830     }
3831   }
3832 
SuspendAudio(void)3833   void SuspendAudio(void) {
3834     CancelStreamingRequest();
3835 
3836     if (sw_enc_left) sw_enc_left.reset();
3837     if (sw_enc_right) sw_enc_right.reset();
3838     if (sw_dec_left) sw_dec_left.reset();
3839     if (sw_dec_right) sw_dec_right.reset();
3840     CleanCachedMicrophoneData();
3841   }
3842 
StopAudio(void)3843   void StopAudio(void) {
3844     SuspendAudio();
3845     L2CA_SetEcosystemBaseInterval(0 /* clear recommendation */);
3846   }
3847 
printCurrentStreamConfiguration(int fd)3848   void printCurrentStreamConfiguration(int fd) {
3849     std::stringstream stream;
3850     auto config_printer = [&stream](LeAudioCodecConfiguration& conf) {
3851       stream << "\tsample rate: " << +conf.sample_rate
3852              << ",\tchan: " << +conf.num_channels
3853              << ",\tbits: " << +conf.bits_per_sample
3854              << ",\tdata_interval_us: " << +conf.data_interval_us << "\n";
3855     };
3856 
3857     stream << " Speaker codec config (audio framework) \n";
3858     stream << "\taudio sender state: " << audio_sender_state_ << "\n";
3859     config_printer(audio_framework_source_config);
3860 
3861     stream << " Microphone codec config (audio framework) \n";
3862     stream << "\taudio receiver state: " << audio_receiver_state_ << "\n";
3863     config_printer(audio_framework_sink_config);
3864 
3865     stream << " Speaker codec config (SW encoder)\n";
3866     config_printer(current_encoder_config_);
3867 
3868     stream << " Microphone codec config (SW decoder)\n";
3869     config_printer(current_decoder_config_);
3870 
3871     dprintf(fd, "%s", stream.str().c_str());
3872   }
3873 
Dump(int fd)3874   void Dump(int fd) {
3875     dprintf(fd, "  APP ID: %d \n", gatt_if_);
3876     dprintf(fd, "  Active group: %d\n", active_group_id_);
3877     dprintf(fd, "  reconnection mode: %s \n",
3878             (reconnection_mode_ == BTM_BLE_BKG_CONNECT_ALLOW_LIST
3879                  ? "Allow List"
3880                  : "Targeted Announcements"));
3881     dprintf(fd, "  configuration: %s  (0x%08x)\n",
3882             bluetooth::common::ToString(configuration_context_type_).c_str(),
3883             static_cast<uint16_t>(configuration_context_type_));
3884     dprintf(fd, "  local source metadata context type mask: %s\n",
3885             local_metadata_context_types_.source.to_string().c_str());
3886     dprintf(fd, "  local sink metadata context type mask: %s\n",
3887             local_metadata_context_types_.sink.to_string().c_str());
3888     dprintf(fd, "  TBS state: %s\n", in_call_ ? " In call" : "No calls");
3889     dprintf(fd, "  Sink listening mode: %s\n",
3890             sink_monitor_mode_ ? "true" : "false");
3891     if (sink_monitor_notified_status_) {
3892       dprintf(fd, "  Local sink notified state: %d\n",
3893               static_cast<int>(sink_monitor_notified_status_.value()));
3894     }
3895     dprintf(fd, "  Source monitor mode: %s\n",
3896             source_monitor_mode_ ? "true" : "false");
3897     dprintf(fd, "  Codec extensibility: %s\n",
3898             CodecManager::GetInstance()->IsUsingCodecExtensibility() ? "true"
3899                                                                      : "false");
3900     dprintf(fd, "  Start time: ");
3901     for (auto t : stream_start_history_queue_) {
3902       dprintf(fd, ", %d ms", static_cast<int>(t));
3903     }
3904     dprintf(fd, "\n");
3905     printCurrentStreamConfiguration(fd);
3906     dprintf(fd, "  ----------------\n ");
3907     dprintf(fd, "  LE Audio Groups:\n");
3908     aseGroups_.Dump(fd, active_group_id_);
3909     dprintf(fd, "\n  Not grouped devices:\n");
3910     leAudioDevices_.Dump(fd, bluetooth::groups::kGroupUnknown);
3911 
3912     if (leAudioHealthStatus_) {
3913       leAudioHealthStatus_->DebugDump(fd);
3914     }
3915   }
3916 
Cleanup()3917   void Cleanup() {
3918     StopVbcCloseTimeout();
3919     if (alarm_is_scheduled(suspend_timeout_)) alarm_cancel(suspend_timeout_);
3920 
3921     if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
3922       /* Bluetooth turned off while streaming */
3923       StopAudio();
3924       SetUnicastMonitorMode(bluetooth::le_audio::types::kLeAudioDirectionSink,
3925                             false);
3926       ClientAudioInterfaceRelease();
3927     } else {
3928       /* There may be not stopped Sink HAL client due to set Listening mode */
3929       if (sink_monitor_mode_) {
3930         SetUnicastMonitorMode(bluetooth::le_audio::types::kLeAudioDirectionSink,
3931                               false);
3932       }
3933     }
3934     groupStateMachine_->Cleanup();
3935     aseGroups_.Cleanup();
3936     lastNotifiedGroupStreamStatusMap_.clear();
3937     leAudioDevices_.Cleanup(gatt_if_);
3938     if (gatt_if_) BTA_GATTC_AppDeregister(gatt_if_);
3939 
3940     if (leAudioHealthStatus_) {
3941       leAudioHealthStatus_->Cleanup();
3942     }
3943   }
3944 
UpdateConfigAndCheckIfReconfigurationIsNeeded(LeAudioDeviceGroup * group,LeAudioContextType context_type)3945   AudioReconfigurationResult UpdateConfigAndCheckIfReconfigurationIsNeeded(
3946       LeAudioDeviceGroup* group, LeAudioContextType context_type) {
3947     log::debug("Checking whether to reconfigure from {} to {}",
3948                ToString(configuration_context_type_), ToString(context_type));
3949 
3950     auto audio_set_conf = group->GetConfiguration(context_type);
3951     if (!audio_set_conf) {
3952       return AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE;
3953     }
3954 
3955     if (group->IsGroupConfiguredTo(*audio_set_conf) &&
3956         !DsaReconfigureNeeded(group, context_type)) {
3957       // Assign the new configuration context as it reprents the current
3958       // use case even when it eventually ends up being the exact same
3959       // codec and qos configuration.
3960       if (configuration_context_type_ != context_type) {
3961         configuration_context_type_ = context_type;
3962         group->SetConfigurationContextType(context_type);
3963       }
3964       return AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED;
3965     }
3966 
3967     log::info("Session reconfiguration needed group: {} for context type: {}",
3968               group->group_id_, ToHexString(context_type));
3969 
3970     configuration_context_type_ = context_type;
3971 
3972     // Note: The local sink config is based on remote device's source config
3973     //       and vice versa.
3974     current_decoder_config_ = group->GetAudioSessionCodecConfigForDirection(
3975         context_type, bluetooth::le_audio::types::kLeAudioDirectionSource);
3976     current_encoder_config_ = group->GetAudioSessionCodecConfigForDirection(
3977         context_type, bluetooth::le_audio::types::kLeAudioDirectionSink);
3978     return AudioReconfigurationResult::RECONFIGURATION_NEEDED;
3979   }
3980 
3981   /* Returns true if stream is started */
OnAudioResume(LeAudioDeviceGroup * group,int local_direction)3982   bool OnAudioResume(LeAudioDeviceGroup* group, int local_direction) {
3983     auto remote_direction =
3984         (local_direction == bluetooth::le_audio::types::kLeAudioDirectionSink
3985              ? bluetooth::le_audio::types::kLeAudioDirectionSource
3986              : bluetooth::le_audio::types::kLeAudioDirectionSink);
3987 
3988     auto remote_contexts =
3989         DirectionalRealignMetadataAudioContexts(group, remote_direction);
3990     ApplyRemoteMetadataAudioContextPolicy(group, remote_contexts,
3991                                           remote_direction);
3992 
3993     if (!remote_contexts.sink.any() && !remote_contexts.source.any()) {
3994       log::warn("Requested context type not available on the remote side");
3995 
3996       if (com::android::bluetooth::flags::leaudio_no_context_validate_streaming_request() &&
3997           source_monitor_mode_) {
3998         callbacks_->OnUnicastMonitorModeStatus(
3999             bluetooth::le_audio::types::kLeAudioDirectionSource,
4000             UnicastMonitorModeStatus::STREAMING_REQUESTED_NO_CONTEXT_VALIDATE);
4001 
4002         return false;
4003       }
4004 
4005       if (leAudioHealthStatus_) {
4006         leAudioHealthStatus_->AddStatisticForGroup(
4007             group, LeAudioHealthGroupStatType::STREAM_CONTEXT_NOT_AVAILABLE);
4008       }
4009       return false;
4010     }
4011 
4012     return GroupStream(active_group_id_, configuration_context_type_,
4013                        remote_contexts);
4014   }
4015 
OnAudioSuspend()4016   void OnAudioSuspend() {
4017     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
4018       log::warn(", there is no longer active group");
4019       return;
4020     }
4021 
4022     if (stack_config_get_interface()
4023             ->get_pts_le_audio_disable_ases_before_stopping()) {
4024       log::info("Stream disable_timer_ started");
4025       if (alarm_is_scheduled(disable_timer_)) alarm_cancel(disable_timer_);
4026 
4027       alarm_set_on_mloop(
4028           disable_timer_, kAudioDisableTimeoutMs,
4029           [](void* data) {
4030             if (instance) instance->GroupSuspend(PTR_TO_INT(data));
4031           },
4032           INT_TO_PTR(active_group_id_));
4033     }
4034 
4035     /* Group should tie in time to get requested status */
4036     uint64_t timeoutMs = kAudioSuspentKeepIsoAliveTimeoutMs;
4037     timeoutMs = osi_property_get_int32(kAudioSuspentKeepIsoAliveTimeoutMsProp,
4038                                        timeoutMs);
4039 
4040     if (stack_config_get_interface()
4041             ->get_pts_le_audio_disable_ases_before_stopping()) {
4042       timeoutMs += kAudioDisableTimeoutMs;
4043     }
4044 
4045     log::debug("Stream suspend_timeout_ started: {} ms",
4046                static_cast<int>(timeoutMs));
4047     if (alarm_is_scheduled(suspend_timeout_)) alarm_cancel(suspend_timeout_);
4048 
4049     alarm_set_on_mloop(
4050         suspend_timeout_, timeoutMs,
4051         [](void* data) {
4052           if (instance) instance->GroupStop(PTR_TO_INT(data));
4053         },
4054         INT_TO_PTR(active_group_id_));
4055   }
4056 
OnLocalAudioSourceSuspend()4057   void OnLocalAudioSourceSuspend() {
4058     log::info(
4059         "active group_id: {}, IN: audio_receiver_state_: {}, "
4060         "audio_sender_state_: {}",
4061         active_group_id_, ToString(audio_receiver_state_),
4062         ToString(audio_sender_state_));
4063     LeAudioLogHistory::Get()->AddLogHistory(
4064         kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4065         kLogAfSuspend + "LocalSource",
4066         "r_state: " + ToString(audio_receiver_state_) +
4067             ", s_state: " + ToString(audio_sender_state_));
4068 
4069     /* Note: This callback is from audio hal driver.
4070      * Bluetooth peer is a Sink for Audio Framework.
4071      * e.g. Peer is a speaker
4072      */
4073     switch (audio_sender_state_) {
4074       case AudioState::READY_TO_START:
4075       case AudioState::STARTED:
4076         audio_sender_state_ = AudioState::READY_TO_RELEASE;
4077         break;
4078       case AudioState::RELEASING:
4079         return;
4080       case AudioState::IDLE:
4081         if (audio_receiver_state_ == AudioState::READY_TO_RELEASE) {
4082           OnAudioSuspend();
4083         }
4084         return;
4085       case AudioState::READY_TO_RELEASE:
4086         break;
4087     }
4088 
4089     /* Last suspends group - triggers group stop */
4090     if ((audio_receiver_state_ == AudioState::IDLE) ||
4091         (audio_receiver_state_ == AudioState::READY_TO_RELEASE)) {
4092       OnAudioSuspend();
4093       bluetooth::le_audio::MetricsCollector::Get()->OnStreamEnded(
4094           active_group_id_);
4095     }
4096 
4097     log::info("OUT: audio_receiver_state_: {},  audio_sender_state_: {}",
4098               ToString(audio_receiver_state_), ToString(audio_sender_state_));
4099 
4100     LeAudioLogHistory::Get()->AddLogHistory(
4101         kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
4102         kLogAfSuspendConfirm + "LocalSource",
4103         "r_state: " + ToString(audio_receiver_state_) +
4104             "s_state: " + ToString(audio_sender_state_));
4105   }
4106 
OnLocalAudioSourceResume()4107   void OnLocalAudioSourceResume() {
4108     log::info(
4109         "active group_id: {}, IN: audio_receiver_state_: {}, "
4110         "audio_sender_state_: {}",
4111         active_group_id_, ToString(audio_receiver_state_),
4112         ToString(audio_sender_state_));
4113     LeAudioLogHistory::Get()->AddLogHistory(
4114         kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4115         kLogAfResume + "LocalSource",
4116         "r_state: " + ToString(audio_receiver_state_) +
4117             ", s_state: " + ToString(audio_sender_state_));
4118 
4119     /* Note: This callback is from audio hal driver.
4120      * Bluetooth peer is a Sink for Audio Framework.
4121      * e.g. Peer is a speaker
4122      */
4123     auto group = aseGroups_.FindById(active_group_id_);
4124     if (!group) {
4125       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4126       return;
4127     }
4128 
4129     /* Check if the device resume is allowed */
4130     if (!group->HasCodecConfigurationForDirection(
4131             configuration_context_type_,
4132             bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4133       log::error("invalid resume request for context type: {}",
4134                  ToHexString(configuration_context_type_));
4135       CancelLocalAudioSourceStreamingRequest();
4136       return;
4137     }
4138 
4139     if (!group
4140              ->GetAllowedContextMask(
4141                  bluetooth::le_audio::types::kLeAudioDirectionSink)
4142              .test(configuration_context_type_)) {
4143       log::warn("Block source resume request context type: {}",
4144                 ToHexString(configuration_context_type_));
4145       CancelLocalAudioSourceStreamingRequest();
4146       return;
4147     }
4148 
4149     log::debug(
4150         "active_group_id: {}\n audio_receiver_state: {}\n audio_sender_state: "
4151         "{}\n configuration_context_type_: {}\n group {}\n",
4152         active_group_id_, audio_receiver_state_, audio_sender_state_,
4153         ToHexString(configuration_context_type_),
4154         group ? " exist " : " does not exist ");
4155 
4156     switch (audio_sender_state_) {
4157       case AudioState::STARTED:
4158         /* Looks like previous Confirm did not get to the Audio Framework*/
4159         ConfirmLocalAudioSourceStreamingRequest();
4160         break;
4161       case AudioState::IDLE:
4162         switch (audio_receiver_state_) {
4163           case AudioState::IDLE:
4164             /* Stream is not started. Try to do it.*/
4165             if (OnAudioResume(
4166                     group,
4167                     bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4168               audio_sender_state_ = AudioState::READY_TO_START;
4169             } else {
4170               CancelLocalAudioSourceStreamingRequest();
4171             }
4172             break;
4173           case AudioState::READY_TO_START:
4174             audio_sender_state_ = AudioState::READY_TO_START;
4175             if (!IsDirectionAvailableForCurrentConfiguration(
4176                     group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4177               log::warn(
4178                   "sink is not configured. \n audio_receiver_state: {} "
4179                   "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4180                   "Reconfiguring to {}",
4181                   ToString(audio_receiver_state_),
4182                   ToString(audio_sender_state_),
4183                   group->IsPendingConfiguration(),
4184                   ToString(configuration_context_type_));
4185               group->PrintDebugState();
4186               SetConfigurationAndStopStreamWhenNeeded(
4187                   group, configuration_context_type_);
4188             }
4189             break;
4190           case AudioState::STARTED:
4191             audio_sender_state_ = AudioState::READY_TO_START;
4192             /* If signalling part is completed trigger start sending audio
4193              * here, otherwise it'll be called on group streaming state callback
4194              */
4195             if (group->GetState() ==
4196                 AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4197               if (IsDirectionAvailableForCurrentConfiguration(
4198                       group,
4199                       bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4200                 StartSendingAudio(active_group_id_);
4201               } else {
4202                 log::warn(
4203                     "sink is not configured. \n audio_receiver_state: {} "
4204                     "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4205                     "Reconfiguring to {}",
4206                     ToString(audio_receiver_state_),
4207                     ToString(audio_sender_state_),
4208                     group->IsPendingConfiguration(),
4209                     ToString(configuration_context_type_));
4210                 group->PrintDebugState();
4211                 SetConfigurationAndStopStreamWhenNeeded(
4212                     group, configuration_context_type_);
4213               }
4214             } else {
4215               log::error(
4216                   "called in wrong state. \n audio_receiver_state: {} "
4217                   "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4218                   "Reconfiguring to {}",
4219                   ToString(audio_receiver_state_),
4220                   ToString(audio_sender_state_),
4221                   group->IsPendingConfiguration(),
4222                   ToString(configuration_context_type_));
4223               group->PrintDebugState();
4224               CancelStreamingRequest();
4225             }
4226             break;
4227           case AudioState::RELEASING:
4228             /* Group is reconfiguring, reassing state and wait for
4229              * the stream to be configured
4230              */
4231             audio_sender_state_ = audio_receiver_state_;
4232             break;
4233           case AudioState::READY_TO_RELEASE:
4234             /* If the other direction is streaming we can start sending audio */
4235             if (group->GetState() ==
4236                 AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4237               if (IsDirectionAvailableForCurrentConfiguration(
4238                       group,
4239                       bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4240                 StartSendingAudio(active_group_id_);
4241               } else {
4242                 log::warn(
4243                     "sink is not configured. \n audio_receiver_state: {} "
4244                     "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4245                     "Reconfiguring to {}",
4246                     ToString(audio_receiver_state_),
4247                     ToString(audio_sender_state_),
4248                     group->IsPendingConfiguration(),
4249                     ToString(configuration_context_type_));
4250                 group->PrintDebugState();
4251                 SetConfigurationAndStopStreamWhenNeeded(
4252                     group, configuration_context_type_);
4253               }
4254             } else {
4255               log::error(
4256                   "called in wrong state. \n audio_receiver_state: {} "
4257                   "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4258                   "Reconfiguring to {}",
4259                   ToString(audio_receiver_state_),
4260                   ToString(audio_sender_state_),
4261                   group->IsPendingConfiguration(),
4262                   ToString(configuration_context_type_));
4263               group->PrintDebugState();
4264               CancelStreamingRequest();
4265             }
4266             break;
4267         }
4268         break;
4269       case AudioState::READY_TO_START:
4270         log::error(
4271             "called in wrong state, ignoring double start request. \n "
4272             "audio_receiver_state: {} \naudio_sender_state: {} \n "
4273             "isPendingConfiguration: {} \n Reconfiguring to {}",
4274             ToString(audio_receiver_state_), ToString(audio_sender_state_),
4275             group->IsPendingConfiguration(),
4276             ToString(configuration_context_type_));
4277         group->PrintDebugState();
4278         break;
4279       case AudioState::READY_TO_RELEASE:
4280         switch (audio_receiver_state_) {
4281           case AudioState::STARTED:
4282           case AudioState::READY_TO_START:
4283           case AudioState::IDLE:
4284           case AudioState::READY_TO_RELEASE:
4285             /* Stream is up just restore it */
4286             if (alarm_is_scheduled(suspend_timeout_))
4287               alarm_cancel(suspend_timeout_);
4288             ConfirmLocalAudioSourceStreamingRequest();
4289             bluetooth::le_audio::MetricsCollector::Get()->OnStreamStarted(
4290                 active_group_id_, configuration_context_type_);
4291             break;
4292           case AudioState::RELEASING:
4293             /* Keep wainting. After release is done, Audio Hal will be notified
4294              */
4295             break;
4296         }
4297         break;
4298       case AudioState::RELEASING:
4299         /* Keep wainting. After release is done, Audio Hal will be notified */
4300         break;
4301     }
4302   }
4303 
OnLocalAudioSinkSuspend()4304   void OnLocalAudioSinkSuspend() {
4305     log::info(
4306         "active group_id: {}, IN: audio_receiver_state_: {}, "
4307         "audio_sender_state_: {}",
4308         active_group_id_, ToString(audio_receiver_state_),
4309         ToString(audio_sender_state_));
4310     LeAudioLogHistory::Get()->AddLogHistory(
4311         kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4312         kLogAfSuspend + "LocalSink",
4313         "r_state: " + ToString(audio_receiver_state_) +
4314             ", s_state: " + ToString(audio_sender_state_));
4315 
4316     StartVbcCloseTimeout();
4317 
4318     /* Note: This callback is from audio hal driver.
4319      * Bluetooth peer is a Source for Audio Framework.
4320      * e.g. Peer is microphone.
4321      */
4322     switch (audio_receiver_state_) {
4323       case AudioState::READY_TO_START:
4324       case AudioState::STARTED:
4325         audio_receiver_state_ = AudioState::READY_TO_RELEASE;
4326         break;
4327       case AudioState::RELEASING:
4328         return;
4329       case AudioState::IDLE:
4330         if (audio_sender_state_ == AudioState::READY_TO_RELEASE) {
4331           OnAudioSuspend();
4332         }
4333         return;
4334       case AudioState::READY_TO_RELEASE:
4335         break;
4336     }
4337 
4338     /* Last suspends group - triggers group stop */
4339     if ((audio_sender_state_ == AudioState::IDLE) ||
4340         (audio_sender_state_ == AudioState::READY_TO_RELEASE))
4341       OnAudioSuspend();
4342 
4343     log::info("OUT: audio_receiver_state_: {},  audio_sender_state_: {}",
4344               ToString(audio_receiver_state_), ToString(audio_sender_state_));
4345 
4346     LeAudioLogHistory::Get()->AddLogHistory(
4347         kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
4348         kLogAfSuspendConfirm + "LocalSink",
4349         "r_state: " + ToString(audio_receiver_state_) +
4350             "s_state: " + ToString(audio_sender_state_));
4351   }
4352 
IsDirectionAvailableForCurrentConfiguration(const LeAudioDeviceGroup * group,uint8_t direction) const4353   inline bool IsDirectionAvailableForCurrentConfiguration(
4354       const LeAudioDeviceGroup* group, uint8_t direction) const {
4355     auto current_config =
4356         group->GetCachedConfiguration(configuration_context_type_);
4357     if (current_config)
4358       return (current_config->confs.get(direction).size() != 0);
4359     return false;
4360   }
4361 
notifyAudioLocalSink(UnicastMonitorModeStatus status)4362   void notifyAudioLocalSink(UnicastMonitorModeStatus status) {
4363     if (sink_monitor_notified_status_ != status) {
4364       log::info("Stream monitoring status changed to: {}",
4365                 static_cast<int>(status));
4366       sink_monitor_notified_status_ = status;
4367       callbacks_->OnUnicastMonitorModeStatus(
4368           bluetooth::le_audio::types::kLeAudioDirectionSink, status);
4369     }
4370   }
4371 
OnLocalAudioSinkResume()4372   void OnLocalAudioSinkResume() {
4373     log::info(
4374         "active group_id: {} IN: audio_receiver_state_: {}, "
4375         "audio_sender_state_: {}",
4376         active_group_id_, ToString(audio_receiver_state_),
4377         ToString(audio_sender_state_));
4378     LeAudioLogHistory::Get()->AddLogHistory(
4379         kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4380         kLogAfResume + "LocalSink",
4381         "r_state: " + ToString(audio_receiver_state_) +
4382             ", s_state: " + ToString(audio_sender_state_));
4383 
4384     if (sink_monitor_mode_ &&
4385         active_group_id_ == bluetooth::groups::kGroupUnknown) {
4386       if (sink_monitor_notified_status_ !=
4387           UnicastMonitorModeStatus::STREAMING_REQUESTED) {
4388         notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_REQUESTED);
4389       }
4390       CancelLocalAudioSinkStreamingRequest();
4391       return;
4392     }
4393 
4394     /* Stop the VBC close watchdog if needed */
4395     StopVbcCloseTimeout();
4396 
4397     /* Note: This callback is from audio hal driver.
4398      * Bluetooth peer is a Source for Audio Framework.
4399      * e.g. Peer is microphone.
4400      */
4401     auto group = aseGroups_.FindById(active_group_id_);
4402     if (!group) {
4403       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4404       return;
4405     }
4406 
4407     /* We need new configuration_context_type_ to be selected before we go any
4408      * further.
4409      */
4410     if (audio_receiver_state_ == AudioState::IDLE) {
4411       ReconfigureOrUpdateRemote(
4412           group, bluetooth::le_audio::types::kLeAudioDirectionSource);
4413     }
4414 
4415     /* Check if the device resume is allowed */
4416     if (!group->HasCodecConfigurationForDirection(
4417             configuration_context_type_,
4418             bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4419       log::error("invalid resume request for context type: {}",
4420                  ToHexString(configuration_context_type_));
4421       CancelLocalAudioSinkStreamingRequest();
4422       return;
4423     }
4424 
4425     if (!group
4426              ->GetAllowedContextMask(
4427                  bluetooth::le_audio::types::kLeAudioDirectionSource)
4428              .test(configuration_context_type_)) {
4429       log::warn("Block sink resume request context type: {}",
4430                 ToHexString(configuration_context_type_));
4431       CancelLocalAudioSourceStreamingRequest();
4432       return;
4433     }
4434 
4435     log::debug(
4436         "active_group_id: {}\n audio_receiver_state: {}\n audio_sender_state: "
4437         "{}\n configuration_context_type_: {}\n group {}\n",
4438         active_group_id_, audio_receiver_state_, audio_sender_state_,
4439         ToHexString(configuration_context_type_),
4440         group ? " exist " : " does not exist ");
4441 
4442     switch (audio_receiver_state_) {
4443       case AudioState::STARTED:
4444         ConfirmLocalAudioSinkStreamingRequest();
4445         break;
4446       case AudioState::IDLE:
4447         switch (audio_sender_state_) {
4448           case AudioState::IDLE:
4449             if (OnAudioResume(
4450                     group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4451               audio_receiver_state_ = AudioState::READY_TO_START;
4452             } else {
4453               CancelLocalAudioSinkStreamingRequest();
4454             }
4455             break;
4456           case AudioState::READY_TO_START:
4457             audio_receiver_state_ = AudioState::READY_TO_START;
4458             if (!IsDirectionAvailableForCurrentConfiguration(
4459                     group,
4460                     bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4461               log::warn(
4462                   "source is not configured. \n audio_receiver_state: {} "
4463                   "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4464                   "Reconfiguring to {}",
4465                   ToString(audio_receiver_state_),
4466                   ToString(audio_sender_state_),
4467                   group->IsPendingConfiguration(),
4468                   ToString(configuration_context_type_));
4469               group->PrintDebugState();
4470               SetConfigurationAndStopStreamWhenNeeded(
4471                   group, configuration_context_type_);
4472             }
4473             break;
4474           case AudioState::STARTED:
4475             audio_receiver_state_ = AudioState::READY_TO_START;
4476             /* If signalling part is completed trigger start receiving audio
4477              * here, otherwise it'll be called on group streaming state callback
4478              */
4479             if (group->GetState() ==
4480                 AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4481               if (IsDirectionAvailableForCurrentConfiguration(
4482                       group,
4483                       bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4484                 StartReceivingAudio(active_group_id_);
4485               } else {
4486                 log::warn(
4487                     "source is not configured. \n audio_receiver_state: {} "
4488                     "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4489                     "Reconfiguring to {}",
4490                     ToString(audio_receiver_state_),
4491                     ToString(audio_sender_state_),
4492                     group->IsPendingConfiguration(),
4493                     ToString(configuration_context_type_));
4494                 group->PrintDebugState();
4495                 SetConfigurationAndStopStreamWhenNeeded(
4496                     group, configuration_context_type_);
4497               }
4498             } else {
4499               log::error(
4500                   "called in wrong state. \n audio_receiver_state: {} "
4501                   "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4502                   "Reconfiguring to {}",
4503                   ToString(audio_receiver_state_),
4504                   ToString(audio_sender_state_),
4505                   group->IsPendingConfiguration(),
4506                   ToString(configuration_context_type_));
4507               group->PrintDebugState();
4508               CancelStreamingRequest();
4509             }
4510             break;
4511           case AudioState::RELEASING:
4512             /* Group is reconfiguring, reassing state and wait for
4513              * the stream to be configured
4514              */
4515             audio_receiver_state_ = audio_sender_state_;
4516             break;
4517           case AudioState::READY_TO_RELEASE:
4518             /* If the other direction is streaming we can start receiving audio
4519              */
4520             if (group->GetState() ==
4521                 AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4522               if (IsDirectionAvailableForCurrentConfiguration(
4523                       group,
4524                       bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4525                 StartReceivingAudio(active_group_id_);
4526               } else {
4527                 log::warn(
4528                     "source is not configured. \n audio_receiver_state: {} "
4529                     "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4530                     "Reconfiguring to {}",
4531                     ToString(audio_receiver_state_),
4532                     ToString(audio_sender_state_),
4533                     group->IsPendingConfiguration(),
4534                     ToString(configuration_context_type_));
4535                 group->PrintDebugState();
4536                 SetConfigurationAndStopStreamWhenNeeded(
4537                     group, configuration_context_type_);
4538               }
4539             } else {
4540               log::error(
4541                   "called in wrong state. \n audio_receiver_state: {} "
4542                   "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4543                   "Reconfiguring to {}",
4544                   ToString(audio_receiver_state_),
4545                   ToString(audio_sender_state_),
4546                   group->IsPendingConfiguration(),
4547                   ToString(configuration_context_type_));
4548               group->PrintDebugState();
4549               CancelStreamingRequest();
4550             }
4551             break;
4552         }
4553         break;
4554       case AudioState::READY_TO_START:
4555         log::error(
4556             "Double resume request, just ignore it.. \n audio_receiver_state: "
4557             "{} \naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4558             "Reconfiguring to {}",
4559             ToString(audio_receiver_state_), ToString(audio_sender_state_),
4560             group->IsPendingConfiguration(),
4561             ToString(configuration_context_type_));
4562         group->PrintDebugState();
4563         break;
4564       case AudioState::READY_TO_RELEASE:
4565         switch (audio_sender_state_) {
4566           case AudioState::STARTED:
4567           case AudioState::IDLE:
4568           case AudioState::READY_TO_START:
4569           case AudioState::READY_TO_RELEASE:
4570             /* Stream is up just restore it */
4571             if (alarm_is_scheduled(suspend_timeout_))
4572               alarm_cancel(suspend_timeout_);
4573             ConfirmLocalAudioSinkStreamingRequest();
4574             break;
4575           case AudioState::RELEASING:
4576             /* Wait until releasing is completed */
4577             break;
4578         }
4579 
4580         break;
4581       case AudioState::RELEASING:
4582         /* Wait until releasing is completed */
4583         break;
4584     }
4585   }
4586 
4587   /* Chooses a single context type to use as a key for selecting a single
4588    * audio set configuration. Contexts used for the metadata can be different
4589    * than this, but it's reasonable to select a configuration context from
4590    * the metadata context types.
4591    */
ChooseConfigurationContextType(AudioContexts available_remote_contexts)4592   LeAudioContextType ChooseConfigurationContextType(
4593       AudioContexts available_remote_contexts) {
4594     log::debug("Got contexts={} in config_context={}",
4595                bluetooth::common::ToString(available_remote_contexts),
4596                bluetooth::common::ToString(configuration_context_type_));
4597 
4598     if (IsInCall()) {
4599       log::debug("In Call preference used.");
4600       return LeAudioContextType::CONVERSATIONAL;
4601     }
4602 
4603     /* Mini policy - always prioritize sink+source configurations so that we are
4604      * sure that for a mixed content we enable all the needed directions.
4605      */
4606     if (available_remote_contexts.any()) {
4607       LeAudioContextType context_priority_list[] = {
4608           /* Highest priority first */
4609           LeAudioContextType::CONVERSATIONAL,
4610           /* Handling RINGTONE will cause the ringtone volume slider to trigger
4611            * reconfiguration. This will be fixed in b/283349711.
4612            */
4613           LeAudioContextType::RINGTONE,
4614           LeAudioContextType::LIVE,
4615           LeAudioContextType::VOICEASSISTANTS,
4616           LeAudioContextType::GAME,
4617           LeAudioContextType::MEDIA,
4618           LeAudioContextType::EMERGENCYALARM,
4619           LeAudioContextType::ALERTS,
4620           LeAudioContextType::INSTRUCTIONAL,
4621           LeAudioContextType::NOTIFICATIONS,
4622           LeAudioContextType::SOUNDEFFECTS,
4623       };
4624       for (auto ct : context_priority_list) {
4625         if (available_remote_contexts.test(ct)) {
4626           log::debug("Selecting configuration context type: {}", ToString(ct));
4627           return ct;
4628         }
4629       }
4630     }
4631 
4632     /* Use BAP mandated UNSPECIFIED only if we don't have any other valid
4633      * configuration
4634      */
4635     auto fallback_config = LeAudioContextType::UNSPECIFIED;
4636     if (configuration_context_type_ != LeAudioContextType::UNINITIALIZED) {
4637       fallback_config = configuration_context_type_;
4638     }
4639 
4640     log::debug("Selecting configuration context type: {}",
4641                ToString(fallback_config));
4642     return fallback_config;
4643   }
4644 
SetConfigurationAndStopStreamWhenNeeded(LeAudioDeviceGroup * group,LeAudioContextType new_context_type)4645   bool SetConfigurationAndStopStreamWhenNeeded(
4646       LeAudioDeviceGroup* group, LeAudioContextType new_context_type) {
4647     auto reconfig_result =
4648         UpdateConfigAndCheckIfReconfigurationIsNeeded(group, new_context_type);
4649     /* Even though the reconfiguration may not be needed, this has
4650      * to be set here as it might be the initial configuration.
4651      */
4652     configuration_context_type_ = new_context_type;
4653 
4654     log::info("group_id {}, context type {} ({}), {}", group->group_id_,
4655               ToString(new_context_type), ToHexString(new_context_type),
4656               ToString(reconfig_result));
4657     if (reconfig_result ==
4658         AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED) {
4659       return false;
4660     }
4661 
4662     if (reconfig_result ==
4663         AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE) {
4664       return false;
4665     }
4666 
4667     if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4668       log::debug("Group is not streaming");
4669       return false;
4670     }
4671 
4672     if (alarm_is_scheduled(suspend_timeout_)) alarm_cancel(suspend_timeout_);
4673 
4674     /* Need to reconfigure stream */
4675     group->SetPendingConfiguration();
4676     groupStateMachine_->StopStream(group);
4677     return true;
4678   }
4679 
OnLocalAudioSourceMetadataUpdate(const std::vector<struct playback_track_metadata_v7> & source_metadata,DsaMode dsa_mode)4680   void OnLocalAudioSourceMetadataUpdate(
4681       const std::vector<struct playback_track_metadata_v7>& source_metadata,
4682       DsaMode dsa_mode) {
4683     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
4684       log::warn(", cannot start streaming if no active group set");
4685       return;
4686     }
4687 
4688     auto group = aseGroups_.FindById(active_group_id_);
4689     if (!group) {
4690       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4691       return;
4692     }
4693 
4694     /* Stop the VBC close timeout timer, since we will reconfigure anyway if the
4695      * VBC was suspended.
4696      */
4697     StopVbcCloseTimeout();
4698 
4699     log::info(
4700         "group_id {} state={}, target_state={}, audio_receiver_state_: {}, "
4701         "audio_sender_state_: {}, dsa_mode: {}",
4702         group->group_id_, ToString(group->GetState()),
4703         ToString(group->GetTargetState()), ToString(audio_receiver_state_),
4704         ToString(audio_sender_state_), static_cast<int>(dsa_mode));
4705 
4706     group->dsa_.mode = dsa_mode;
4707 
4708     /* Set the remote sink metadata context from the playback tracks metadata */
4709     local_metadata_context_types_.source =
4710         GetAudioContextsFromSourceMetadata(source_metadata);
4711 
4712     local_metadata_context_types_.sink =
4713         ChooseMetadataContextType(local_metadata_context_types_.sink);
4714     local_metadata_context_types_.source =
4715         ChooseMetadataContextType(local_metadata_context_types_.source);
4716 
4717     ReconfigureOrUpdateRemote(
4718         group, bluetooth::le_audio::types::kLeAudioDirectionSink);
4719   }
4720 
4721   /* Applies some predefined policy on the audio context metadata, including
4722    * special handling of UNSPECIFIED context, which also involves checking
4723    * context support and availability.
4724    */
ApplyRemoteMetadataAudioContextPolicy(LeAudioDeviceGroup * group,BidirectionalPair<AudioContexts> & contexts_pair,int remote_dir)4725   void ApplyRemoteMetadataAudioContextPolicy(
4726       LeAudioDeviceGroup* group,
4727       BidirectionalPair<AudioContexts>& contexts_pair, int remote_dir) {
4728     // We expect at least some context when this direction gets enabled
4729     if (contexts_pair.get(remote_dir).none()) {
4730       log::warn(
4731           "invalid/unknown {} context metadata, using 'UNSPECIFIED' instead",
4732           (remote_dir == bluetooth::le_audio::types::kLeAudioDirectionSink)
4733               ? "sink"
4734               : "source");
4735       contexts_pair.get(remote_dir) =
4736           AudioContexts(LeAudioContextType::UNSPECIFIED);
4737     }
4738 
4739     std::tuple<int, int, AudioState*> remote_directions[] = {
4740         {bluetooth::le_audio::types::kLeAudioDirectionSink,
4741          bluetooth::le_audio::types::kLeAudioDirectionSource,
4742          &audio_sender_state_},
4743         {bluetooth::le_audio::types::kLeAudioDirectionSource,
4744          bluetooth::le_audio::types::kLeAudioDirectionSink,
4745          &audio_receiver_state_},
4746     };
4747 
4748     /* Align with the context availability */
4749     for (auto entry : remote_directions) {
4750       int dir, other_dir;
4751       AudioState* local_hal_state;
4752       std::tie(dir, other_dir, local_hal_state) = entry;
4753 
4754       /* When a certain context became unavailable while it was already in
4755        * an active stream, it means that it is unavailable to other clients
4756        * but we can keep using it.
4757        */
4758       auto group_available_contexts = group->GetAvailableContexts(dir);
4759       if ((*local_hal_state == AudioState::STARTED) ||
4760           (*local_hal_state == AudioState::READY_TO_START)) {
4761         group_available_contexts |= group->GetMetadataContexts().get(dir);
4762       }
4763 
4764       log::debug("Checking contexts: {}, against the available contexts: {}",
4765                  ToString(contexts_pair.get(dir)),
4766                  ToString(group_available_contexts));
4767       auto unavail_contexts =
4768           contexts_pair.get(dir) & ~group_available_contexts;
4769       if (unavail_contexts.none()) continue;
4770 
4771       contexts_pair.get(dir) &= group_available_contexts;
4772       auto unavail_but_supported =
4773           (unavail_contexts & group->GetSupportedContexts(dir));
4774       if (unavail_but_supported.none() &&
4775           group_available_contexts.test(LeAudioContextType::UNSPECIFIED)) {
4776         log::debug("Replaced the unsupported contexts: {} with UNSPECIFIED",
4777                    ToString(unavail_contexts));
4778         /* All unavailable are also unsupported - replace with UNSPECIFIED if
4779          * available
4780          */
4781         contexts_pair.get(dir).set(LeAudioContextType::UNSPECIFIED);
4782       } else {
4783         log::debug("Some contexts are supported but currently unavailable: {}!",
4784                    ToString(unavail_but_supported));
4785         /* Some of the streamed contexts are support but not available and they
4786          * were erased from the metadata.
4787          * TODO: Either filter out these contexts from the stream or do not
4788          * stream at all if the unavail_but_supported contexts are the only
4789          * streamed contexts.
4790          */
4791       }
4792     }
4793 
4794     /* Don't mix UNSPECIFIED with any other context
4795      * Note: This has to be in a separate loop - do not merge it with the above.
4796      */
4797     for (auto entry : remote_directions) {
4798       int dir, other_dir;
4799       AudioState* local_hal_state;
4800       std::tie(dir, other_dir, local_hal_state) = entry;
4801 
4802       if (contexts_pair.get(dir).test(LeAudioContextType::UNSPECIFIED)) {
4803         /* Try to use the other direction context if not UNSPECIFIED and active
4804          */
4805         if (contexts_pair.get(dir) ==
4806             AudioContexts(LeAudioContextType::UNSPECIFIED)) {
4807           auto is_other_direction_streaming =
4808               (*local_hal_state == AudioState::STARTED) ||
4809               (*local_hal_state == AudioState::READY_TO_START);
4810           if (is_other_direction_streaming &&
4811               (contexts_pair.get(other_dir) !=
4812                AudioContexts(LeAudioContextType::UNSPECIFIED))) {
4813             log::info(
4814                 "Other direction is streaming. Aligning other direction "
4815                 "metadata to match the current direciton context: {}",
4816                 ToString(contexts_pair.get(other_dir)));
4817             contexts_pair.get(dir) = contexts_pair.get(other_dir);
4818           }
4819         } else {
4820           log::debug("Removing UNSPECIFIED from the remote sink context: {}",
4821                      ToString(contexts_pair.get(other_dir)));
4822           contexts_pair.get(dir).unset(LeAudioContextType::UNSPECIFIED);
4823         }
4824       }
4825     }
4826 
4827     contexts_pair.sink = ChooseMetadataContextType(contexts_pair.sink);
4828     contexts_pair.source = ChooseMetadataContextType(contexts_pair.source);
4829 
4830     log::debug("Aligned remote metadata audio context: sink={}, source={}",
4831                ToString(contexts_pair.sink), ToString(contexts_pair.source));
4832   }
4833 
OnLocalAudioSinkMetadataUpdate(const std::vector<record_track_metadata_v7> & sink_metadata)4834   void OnLocalAudioSinkMetadataUpdate(
4835       const std::vector<record_track_metadata_v7>& sink_metadata) {
4836     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
4837       log::warn(", cannot start streaming if no active group set");
4838       return;
4839     }
4840 
4841     auto group = aseGroups_.FindById(active_group_id_);
4842     if (!group) {
4843       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4844       return;
4845     }
4846 
4847     log::info(
4848         "group_id {} state={}, target_state={}, audio_receiver_state_: {}, "
4849         "audio_sender_state_: {}",
4850         group->group_id_, ToString(group->GetState()),
4851         ToString(group->GetTargetState()), ToString(audio_receiver_state_),
4852         ToString(audio_sender_state_));
4853 
4854     /* Set remote source metadata context from the recording tracks metadata */
4855     local_metadata_context_types_.sink =
4856         GetAudioContextsFromSinkMetadata(sink_metadata);
4857 
4858     local_metadata_context_types_.sink =
4859         ChooseMetadataContextType(local_metadata_context_types_.sink);
4860     local_metadata_context_types_.source =
4861         ChooseMetadataContextType(local_metadata_context_types_.source);
4862 
4863     /* Reconfigure or update only if the stream is already started
4864      * otherwise wait for the local sink to resume.
4865      */
4866     if (audio_receiver_state_ == AudioState::STARTED) {
4867       ReconfigureOrUpdateRemote(
4868           group, bluetooth::le_audio::types::kLeAudioDirectionSource);
4869     }
4870   }
4871 
DirectionalRealignMetadataAudioContexts(LeAudioDeviceGroup * group,int remote_direction)4872   BidirectionalPair<AudioContexts> DirectionalRealignMetadataAudioContexts(
4873       LeAudioDeviceGroup* group, int remote_direction) {
4874     auto remote_other_direction =
4875         (remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSink
4876              ? bluetooth::le_audio::types::kLeAudioDirectionSource
4877              : bluetooth::le_audio::types::kLeAudioDirectionSink);
4878     auto other_direction_hal =
4879         (remote_other_direction ==
4880                  bluetooth::le_audio::types::kLeAudioDirectionSource
4881              ? audio_receiver_state_
4882              : audio_sender_state_);
4883     auto is_streaming_other_direction =
4884         (other_direction_hal == AudioState::STARTED) ||
4885         (other_direction_hal == AudioState::READY_TO_START);
4886     auto is_releasing_for_reconfiguration =
4887         (((audio_receiver_state_ == AudioState::RELEASING) ||
4888           (audio_sender_state_ == AudioState::RELEASING)) &&
4889          group->IsPendingConfiguration() &&
4890          IsDirectionAvailableForCurrentConfiguration(group,
4891                                                      remote_other_direction));
4892 
4893     // Inject conversational when ringtone is played - this is required for all
4894     // the VoIP applications which are not using the telecom API.
4895     constexpr AudioContexts possible_voip_contexts =
4896         LeAudioContextType::RINGTONE | LeAudioContextType::CONVERSATIONAL;
4897     if (local_metadata_context_types_.source.test_any(possible_voip_contexts) &&
4898         ((remote_direction ==
4899           bluetooth::le_audio::types::kLeAudioDirectionSink) ||
4900          (remote_direction ==
4901               bluetooth::le_audio::types::kLeAudioDirectionSource &&
4902           is_streaming_other_direction))) {
4903       /* Simulate, we are already in the call. Sending RINGTONE when there is
4904        * no incoming call to accept or reject on TBS could confuse the remote
4905        * device and interrupt the stream establish procedure.
4906        */
4907       if (!IsInCall()) {
4908         SetInVoipCall(true);
4909       }
4910     } else if (IsInVoipCall()) {
4911       SetInVoipCall(false);
4912     }
4913 
4914     /* Make sure we have CONVERSATIONAL when in a call and it is not mixed
4915      * with any other bidirectional context
4916      */
4917     if (IsInCall() || IsInVoipCall()) {
4918       log::debug("In Call preference used: {}, voip call: {}", IsInCall(),
4919                  IsInVoipCall());
4920       local_metadata_context_types_.sink.unset_all(kLeAudioContextAllBidir);
4921       local_metadata_context_types_.source.unset_all(kLeAudioContextAllBidir);
4922       local_metadata_context_types_.sink.set(
4923           LeAudioContextType::CONVERSATIONAL);
4924       local_metadata_context_types_.source.set(
4925           LeAudioContextType::CONVERSATIONAL);
4926     }
4927 
4928     BidirectionalPair<AudioContexts> remote_metadata = {
4929         .sink = local_metadata_context_types_.source,
4930         .source = local_metadata_context_types_.sink};
4931 
4932     if (IsInVoipCall()) {
4933       log::debug("Unsetting RINGTONE from remote sink");
4934       remote_metadata.sink.unset(LeAudioContextType::RINGTONE);
4935     }
4936 
4937     auto is_ongoing_call_on_other_direction =
4938         is_streaming_other_direction && (IsInVoipCall() || IsInCall());
4939 
4940     log::debug("local_metadata_context_types_.source= {}",
4941                ToString(local_metadata_context_types_.source));
4942     log::debug("local_metadata_context_types_.sink= {}",
4943                ToString(local_metadata_context_types_.sink));
4944     log::debug("remote_metadata.source= {}", ToString(remote_metadata.source));
4945     log::debug("remote_metadata.sink= {}", ToString(remote_metadata.sink));
4946     log::debug(
4947         "remote_direction= {}",
4948         (remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSource
4949              ? "Source"
4950              : "Sink"));
4951     log::debug("is_streaming_other_direction= {}",
4952                is_streaming_other_direction ? "True" : "False");
4953     log::debug("is_releasing_for_reconfiguration= {}",
4954                is_releasing_for_reconfiguration ? "True" : "False");
4955     log::debug("is_ongoing_call_on_other_direction={}",
4956                is_ongoing_call_on_other_direction ? "True" : "False");
4957 
4958     if (remote_metadata.get(remote_other_direction)
4959             .test_any(kLeAudioContextAllBidir) &&
4960         !is_streaming_other_direction) {
4961       log::debug(
4962           "The other direction is not streaming bidirectional, ignore that "
4963           "context.");
4964       remote_metadata.get(remote_other_direction).clear();
4965     }
4966 
4967     /* Mixed contexts in the voiceback channel scenarios can confuse the remote
4968      * on how to configure each channel. We should align the other direction
4969      * metadata for the remote device.
4970      */
4971     if (remote_metadata.get(remote_direction)
4972             .test_any(kLeAudioContextAllBidir)) {
4973       log::debug(
4974           "Aligning the other direction remote metadata to add this direction "
4975           "context");
4976 
4977       if (is_ongoing_call_on_other_direction) {
4978         /* Other direction is streaming and is in call */
4979         remote_metadata.get(remote_direction)
4980             .unset_all(kLeAudioContextAllBidir);
4981         remote_metadata.get(remote_direction)
4982             .set(LeAudioContextType::CONVERSATIONAL);
4983       } else {
4984         if (!is_streaming_other_direction) {
4985           // Do not take the obsolete metadata
4986           remote_metadata.get(remote_other_direction).clear();
4987         }
4988         remote_metadata.get(remote_other_direction)
4989             .unset_all(kLeAudioContextAllBidir);
4990         remote_metadata.get(remote_other_direction)
4991             .unset_all(kLeAudioContextAllRemoteSinkOnly);
4992         remote_metadata.get(remote_other_direction)
4993             .set_all(remote_metadata.get(remote_direction) &
4994                      ~kLeAudioContextAllRemoteSinkOnly);
4995       }
4996     }
4997     log::debug("remote_metadata.source= {}", ToString(remote_metadata.source));
4998     log::debug("remote_metadata.sink= {}", ToString(remote_metadata.sink));
4999 
5000     if (is_releasing_for_reconfiguration || is_streaming_other_direction) {
5001       log::debug("Other direction is streaming. Taking its contexts {}",
5002                  ToString(remote_metadata.get(remote_other_direction)));
5003       /* If current direction has no valid context or the other direction is
5004        * bidirectional scenario, take the other direction context as well
5005        */
5006       if ((remote_metadata.get(remote_direction).none() &&
5007            remote_metadata.get(remote_other_direction).any()) ||
5008           remote_metadata.get(remote_other_direction)
5009               .test_any(kLeAudioContextAllBidir)) {
5010         log::debug(
5011             "Aligning this direction remote metadata to add the other "
5012             "direction context");
5013         /* Turn off bidirectional contexts on this direction to avoid mixing
5014          * with the other direction bidirectional context
5015          */
5016         remote_metadata.get(remote_direction)
5017             .unset_all(kLeAudioContextAllBidir);
5018         remote_metadata.get(remote_direction)
5019             .set_all(remote_metadata.get(remote_other_direction));
5020       }
5021     }
5022 
5023     /* Make sure that after alignment no sink only context leaks into the other
5024      * direction. */
5025     remote_metadata.source.unset_all(kLeAudioContextAllRemoteSinkOnly);
5026 
5027     log::debug("remote_metadata.source= {}", ToString(remote_metadata.source));
5028     log::debug("remote_metadata.sink= {}", ToString(remote_metadata.sink));
5029     return remote_metadata;
5030   }
5031 
AdjustForVoiceAssistant(LeAudioDeviceGroup * group,LeAudioContextType new_configuration_context)5032   LeAudioContextType AdjustForVoiceAssistant(
5033       LeAudioDeviceGroup* group, LeAudioContextType new_configuration_context) {
5034     if (!com::android::bluetooth::flags::
5035             le_audio_support_unidirectional_voice_assistant()) {
5036       log::debug(
5037           "Flag le_audio_support_unidirectional_voice_assistant NOT enabled");
5038       return new_configuration_context;
5039     }
5040 
5041     /* Some remote devices expect VOICE ASSISTANT to be unidirectional Phone is
5042      * Source and Earbuds are Sink */
5043     if (new_configuration_context != LeAudioContextType::VOICEASSISTANTS) {
5044       return new_configuration_context;
5045     }
5046 
5047     auto sink_supported_contexts = group->GetSupportedContexts(
5048         bluetooth::le_audio::types::kLeAudioDirectionSink);
5049     auto source_supported_contexts = group->GetSupportedContexts(
5050         bluetooth::le_audio::types::kLeAudioDirectionSource);
5051 
5052     log::debug("group_id: {}, sink_supported: {}, source_supported {}",
5053                group->group_id_, ToString(sink_supported_contexts),
5054                ToString(source_supported_contexts));
5055     if (sink_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS) &&
5056         source_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS)) {
5057       return new_configuration_context;
5058     }
5059 
5060     if (sink_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS)) {
5061       log::info(
5062           "group_id {} supports only Sink direction for Voice Assistant. "
5063           "Selecting configurarion context type {}",
5064           group->group_id_, ToString(LeAudioContextType::INSTRUCTIONAL));
5065 
5066       return LeAudioContextType::INSTRUCTIONAL;
5067     }
5068 
5069     log::warn(
5070         "group_id: {},  unexpected configuration, sink_supported: {}, "
5071         "source_supported {}",
5072         group->group_id_, ToString(sink_supported_contexts),
5073         ToString(source_supported_contexts));
5074     return new_configuration_context;
5075   }
5076 
5077   /* Return true if stream is started */
ReconfigureOrUpdateRemote(LeAudioDeviceGroup * group,int remote_direction)5078   bool ReconfigureOrUpdateRemote(LeAudioDeviceGroup* group,
5079                                  int remote_direction) {
5080     if (stack_config_get_interface()
5081             ->get_pts_force_le_audio_multiple_contexts_metadata()) {
5082       // Use common audio stream contexts exposed by the PTS
5083       auto override_contexts = AudioContexts(0xFFFF);
5084       for (auto device = group->GetFirstDevice(); device != nullptr;
5085            device = group->GetNextDevice(device)) {
5086         override_contexts &= device->GetAvailableContexts();
5087       }
5088       if (override_contexts.value() == 0xFFFF) {
5089         override_contexts = AudioContexts(LeAudioContextType::UNSPECIFIED);
5090       }
5091       log::warn("Overriding local_metadata_context_types_: {} with: {}",
5092                 local_metadata_context_types_.source.to_string(),
5093                 override_contexts.to_string());
5094 
5095       /* Choose the right configuration context */
5096       auto new_configuration_context = AdjustForVoiceAssistant(
5097           group, ChooseConfigurationContextType(override_contexts));
5098 
5099       log::debug("new_configuration_context= {}.",
5100                  ToString(new_configuration_context));
5101       BidirectionalPair<AudioContexts> remote_contexts = {
5102           .sink = override_contexts, .source = override_contexts};
5103       return GroupStream(active_group_id_, new_configuration_context,
5104                          remote_contexts);
5105     }
5106 
5107     /* When the local sink and source update their metadata, we need to come up
5108      * with a coherent set of contexts for either one or both directions,
5109      * especially when bidirectional scenarios can be triggered be either sink
5110      * or source metadata update event.
5111      */
5112     auto remote_metadata =
5113         DirectionalRealignMetadataAudioContexts(group, remote_direction);
5114 
5115     /* Choose the right configuration context */
5116     auto config_context_candids = get_bidirectional(remote_metadata);
5117     auto new_config_context = AdjustForVoiceAssistant(
5118         group, ChooseConfigurationContextType(config_context_candids));
5119     log::debug("config_context_candids= {}, new_config_context= {}",
5120                ToString(config_context_candids), ToString(new_config_context));
5121 
5122     /* For the following contexts we don't actually need HQ audio:
5123      * LeAudioContextType::NOTIFICATIONS
5124      * LeAudioContextType::SOUNDEFFECTS
5125      * LeAudioContextType::INSTRUCTIONAL
5126      * LeAudioContextType::ALERTS
5127      * LeAudioContextType::EMERGENCYALARM
5128      * LeAudioContextType::UNSPECIFIED
5129      * So do not reconfigure if the remote sink is already available at any
5130      * quality and these are the only contributors to the current audio stream.
5131      */
5132     auto no_reconfigure_contexts =
5133         LeAudioContextType::NOTIFICATIONS | LeAudioContextType::SOUNDEFFECTS |
5134         LeAudioContextType::INSTRUCTIONAL | LeAudioContextType::ALERTS |
5135         LeAudioContextType::EMERGENCYALARM | LeAudioContextType::UNSPECIFIED;
5136     if (group->IsStreaming() && config_context_candids.any() &&
5137         (config_context_candids & ~no_reconfigure_contexts).none() &&
5138         (configuration_context_type_ != LeAudioContextType::UNINITIALIZED) &&
5139         (configuration_context_type_ != LeAudioContextType::UNSPECIFIED) &&
5140         IsDirectionAvailableForCurrentConfiguration(
5141             group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
5142       log::info(
5143           "There is no need to reconfigure for the sonification events, "
5144           "staying with the existing configuration context of {}",
5145           ToString(configuration_context_type_));
5146       new_config_context = configuration_context_type_;
5147     }
5148 
5149     /* Do not configure the Voiceback channel if it is already configured.
5150      * WARNING: This eliminates additional reconfigurations but can
5151      * lead to unsatisfying audio quality when that direction was
5152      * already configured with a lower quality.
5153      */
5154     if (remote_direction ==
5155         bluetooth::le_audio::types::kLeAudioDirectionSource) {
5156       const auto has_audio_source_configured =
5157           IsDirectionAvailableForCurrentConfiguration(
5158               group, bluetooth::le_audio::types::kLeAudioDirectionSource) &&
5159           (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5160       if (has_audio_source_configured) {
5161         log::info(
5162             "Audio source is already available in the current configuration "
5163             "context in {}. Not switching to {} right now.",
5164             ToString(configuration_context_type_),
5165             ToString(new_config_context));
5166         new_config_context = configuration_context_type_;
5167       }
5168     }
5169 
5170     /* Note that the remote device metadata was so far unfiltered when it comes
5171      * to group context availability, or multiple contexts support flag, so that
5172      * we could choose the correct configuration for the use case. Now we can
5173      * align it to meet the metadata usage.
5174      */
5175     ApplyRemoteMetadataAudioContextPolicy(group, remote_metadata,
5176                                           remote_direction);
5177     return ReconfigureOrUpdateMetadata(group, new_config_context,
5178                                        remote_metadata);
5179   }
5180 
DsaReconfigureNeeded(LeAudioDeviceGroup * group,LeAudioContextType context)5181   bool DsaReconfigureNeeded(LeAudioDeviceGroup* group,
5182                             LeAudioContextType context) {
5183     if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
5184       return false;
5185     }
5186 
5187     // Reconfigure if DSA mode changed for media streaming
5188     if (context != bluetooth::le_audio::types::LeAudioContextType::MEDIA) {
5189       return false;
5190     }
5191 
5192     if (group->dsa_.mode != DsaMode::ISO_SW &&
5193         group->dsa_.mode != DsaMode::ISO_HW) {
5194       return false;
5195     }
5196 
5197     if (group->dsa_.active) {
5198       return false;
5199     }
5200 
5201     log::info("DSA mode {} requested but not active", group->dsa_.mode);
5202     return true;
5203   }
5204 
5205   /* Return true if stream is started */
ReconfigureOrUpdateMetadata(LeAudioDeviceGroup * group,LeAudioContextType new_configuration_context,BidirectionalPair<AudioContexts> remote_contexts)5206   bool ReconfigureOrUpdateMetadata(
5207       LeAudioDeviceGroup* group, LeAudioContextType new_configuration_context,
5208       BidirectionalPair<AudioContexts> remote_contexts) {
5209     if (new_configuration_context != configuration_context_type_ ||
5210         DsaReconfigureNeeded(group, new_configuration_context)) {
5211       log::info(
5212           "Checking whether to change configuration context from {} to {}",
5213           ToString(configuration_context_type_),
5214           ToString(new_configuration_context));
5215 
5216       LeAudioLogHistory::Get()->AddLogHistory(
5217           kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
5218           kLogAfMetadataUpdate + "Reconfigure",
5219           ToString(configuration_context_type_) + "->" +
5220               ToString(new_configuration_context));
5221       auto is_stopping = SetConfigurationAndStopStreamWhenNeeded(
5222           group, new_configuration_context);
5223       if (is_stopping) {
5224         return false;
5225       }
5226     }
5227 
5228     if (group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
5229       log::info(
5230           "The {} configuration did not change. Updating the metadata to "
5231           "sink={}, source={}",
5232           ToString(configuration_context_type_), ToString(remote_contexts.sink),
5233           ToString(remote_contexts.source));
5234 
5235       LeAudioLogHistory::Get()->AddLogHistory(
5236           kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
5237           kLogAfMetadataUpdate + "Updating...",
5238           "Sink: " + ToString(remote_contexts.sink) +
5239               "Source: " + ToString(remote_contexts.source));
5240 
5241       return GroupStream(group->group_id_, configuration_context_type_,
5242                          remote_contexts);
5243     }
5244     return false;
5245   }
5246 
OnGattCtpCccReadRspStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t hdl,uint16_t len,uint8_t * value,void * data)5247   static void OnGattCtpCccReadRspStatic(uint16_t conn_id, tGATT_STATUS status,
5248                                         uint16_t hdl, uint16_t len,
5249                                         uint8_t* value, void* data) {
5250     if (!instance) return;
5251 
5252     log::debug("conn_id: 0x{:04x}, status: 0x{:02x}", conn_id, status);
5253 
5254     LeAudioDevice* leAudioDevice =
5255         instance->leAudioDevices_.FindByConnId(conn_id);
5256 
5257     if (!leAudioDevice) {
5258       log::error("LeAudioDevice not found");
5259       return;
5260     }
5261 
5262     if (status == GATT_DATABASE_OUT_OF_SYNC) {
5263       log::info("Database out of sync for {}, re-discovering",
5264                 leAudioDevice->address_);
5265       instance->ClearDeviceInformationAndStartSearch(leAudioDevice);
5266       return;
5267     }
5268 
5269     if (status != GATT_SUCCESS || len != 2) {
5270       log::error("Could not read CCC for {}, disconnecting",
5271                  leAudioDevice->address_);
5272       instance->Disconnect(leAudioDevice->address_);
5273       return;
5274     }
5275 
5276     uint16_t val = *(uint16_t*)value;
5277     if (val == 0) {
5278       log::info("{} forgot CCC values. Re-subscribing",
5279                 leAudioDevice->address_);
5280       instance->RegisterKnownNotifications(leAudioDevice, false, true);
5281     } else {
5282       instance->connectionReady(leAudioDevice);
5283     }
5284   }
5285 
OnGattReadRspStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t hdl,uint16_t len,uint8_t * value,void * data)5286   static void OnGattReadRspStatic(uint16_t conn_id, tGATT_STATUS status,
5287                                   uint16_t hdl, uint16_t len, uint8_t* value,
5288                                   void* data) {
5289     if (!instance) return;
5290 
5291     LeAudioDevice* leAudioDevice =
5292         instance->leAudioDevices_.FindByConnId(conn_id);
5293 
5294     if (status == GATT_SUCCESS) {
5295       instance->LeAudioCharValueHandle(conn_id, hdl, len, value);
5296     } else if (status == GATT_DATABASE_OUT_OF_SYNC) {
5297       instance->ClearDeviceInformationAndStartSearch(leAudioDevice);
5298       return;
5299     } else {
5300       log::error("Failed to read attribute, hdl: 0x{:04x}, status: 0x{:02x}",
5301                  hdl, static_cast<int>(status));
5302       return;
5303     }
5304 
5305     /* We use data to keep notify connected flag. */
5306     if (data && !!PTR_TO_INT(data)) {
5307       leAudioDevice->notify_connected_after_read_ = false;
5308 
5309       /* Update handles, PACs and ASEs when all is read.*/
5310       btif_storage_leaudio_update_handles_bin(leAudioDevice->address_);
5311       btif_storage_leaudio_update_pacs_bin(leAudioDevice->address_);
5312       btif_storage_leaudio_update_ase_bin(leAudioDevice->address_);
5313 
5314       btif_storage_set_leaudio_audio_location(
5315           leAudioDevice->address_,
5316           leAudioDevice->snk_audio_locations_.to_ulong(),
5317           leAudioDevice->src_audio_locations_.to_ulong());
5318 
5319       instance->connectionReady(leAudioDevice);
5320     }
5321   }
5322 
LeAudioHealthSendRecommendation(const RawAddress & address,int group_id,LeAudioHealthBasedAction action)5323   void LeAudioHealthSendRecommendation(const RawAddress& address, int group_id,
5324                                        LeAudioHealthBasedAction action) {
5325     log::debug("{}, {}, {}", address, group_id, ToString(action));
5326 
5327     if (address != RawAddress::kEmpty &&
5328         leAudioDevices_.FindByAddress(address)) {
5329       callbacks_->OnHealthBasedRecommendationAction(address, action);
5330     }
5331 
5332     if (group_id != bluetooth::groups::kGroupUnknown &&
5333         aseGroups_.FindById(group_id)) {
5334       callbacks_->OnHealthBasedGroupRecommendationAction(group_id, action);
5335     }
5336   }
5337 
IsoCigEventsCb(uint16_t event_type,void * data)5338   void IsoCigEventsCb(uint16_t event_type, void* data) {
5339     switch (event_type) {
5340       case bluetooth::hci::iso_manager::kIsoEventCigOnCreateCmpl: {
5341         auto* evt = static_cast<cig_create_cmpl_evt*>(data);
5342         LeAudioDeviceGroup* group = aseGroups_.FindById(evt->cig_id);
5343         log::assert_that(group, "Group id: {} is null", evt->cig_id);
5344         groupStateMachine_->ProcessHciNotifOnCigCreate(
5345             group, evt->status, evt->cig_id, evt->conn_handles);
5346       } break;
5347       case bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl: {
5348         auto* evt = static_cast<cig_remove_cmpl_evt*>(data);
5349         LeAudioDeviceGroup* group = aseGroups_.FindById(evt->cig_id);
5350         log::assert_that(group, "Group id: {} is null", evt->cig_id);
5351         groupStateMachine_->ProcessHciNotifOnCigRemove(evt->status, group);
5352         remove_group_if_possible(group);
5353       } break;
5354       default:
5355         log::error("Invalid event {}", event_type);
5356     }
5357   }
5358 
IsoCisEventsCb(uint16_t event_type,void * data)5359   void IsoCisEventsCb(uint16_t event_type, void* data) {
5360     switch (event_type) {
5361       case bluetooth::hci::iso_manager::kIsoEventCisDataAvailable: {
5362         auto* event =
5363             static_cast<bluetooth::hci::iso_manager::cis_data_evt*>(data);
5364 
5365         if (DsaDataConsume(event)) {
5366           return;
5367         }
5368 
5369         if (audio_receiver_state_ != AudioState::STARTED) {
5370           log::error("receiver state not ready, current state={}",
5371                      ToString(audio_receiver_state_));
5372           break;
5373         }
5374 
5375         HandleIncomingCisData(event->p_msg->data + event->p_msg->offset,
5376                               event->p_msg->len - event->p_msg->offset,
5377                               event->cis_conn_hdl, event->ts);
5378       } break;
5379       case bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl: {
5380         auto* event =
5381             static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(
5382                 data);
5383 
5384         LeAudioDevice* leAudioDevice = leAudioDevices_.FindByCisConnHdl(
5385             event->cig_id, event->cis_conn_hdl);
5386         if (!leAudioDevice) {
5387           log::error("no bonded Le Audio Device with CIS: {}",
5388                      event->cis_conn_hdl);
5389           break;
5390         }
5391         LeAudioDeviceGroup* group =
5392             aseGroups_.FindById(leAudioDevice->group_id_);
5393 
5394         if (event->max_pdu_mtos > 0)
5395           group->SetTransportLatency(
5396               bluetooth::le_audio::types::kLeAudioDirectionSink,
5397               event->trans_lat_mtos);
5398         if (event->max_pdu_stom > 0)
5399           group->SetTransportLatency(
5400               bluetooth::le_audio::types::kLeAudioDirectionSource,
5401               event->trans_lat_stom);
5402 
5403         if (leAudioHealthStatus_ && (event->status != HCI_SUCCESS)) {
5404           leAudioHealthStatus_->AddStatisticForGroup(
5405               group, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
5406         }
5407 
5408         groupStateMachine_->ProcessHciNotifCisEstablished(group, leAudioDevice,
5409                                                           event);
5410       } break;
5411       case bluetooth::hci::iso_manager::kIsoEventCisDisconnected: {
5412         auto* event =
5413             static_cast<bluetooth::hci::iso_manager::cis_disconnected_evt*>(
5414                 data);
5415 
5416         LeAudioDevice* leAudioDevice = leAudioDevices_.FindByCisConnHdl(
5417             event->cig_id, event->cis_conn_hdl);
5418         if (!leAudioDevice) {
5419           log::error("no bonded Le Audio Device with CIS: {}",
5420                      event->cis_conn_hdl);
5421           break;
5422         }
5423         LeAudioDeviceGroup* group =
5424             aseGroups_.FindById(leAudioDevice->group_id_);
5425 
5426         groupStateMachine_->ProcessHciNotifCisDisconnected(group, leAudioDevice,
5427                                                            event);
5428       } break;
5429       default:
5430         log::info(", Not handeled ISO event");
5431         break;
5432     }
5433   }
5434 
IsoSetupIsoDataPathCb(uint8_t status,uint16_t conn_handle,uint8_t cig_id)5435   void IsoSetupIsoDataPathCb(uint8_t status, uint16_t conn_handle,
5436                              uint8_t cig_id) {
5437     LeAudioDevice* leAudioDevice =
5438         leAudioDevices_.FindByCisConnHdl(cig_id, conn_handle);
5439     /* In case device has been disconnected before data path was setup */
5440     if (!leAudioDevice) {
5441       log::warn(
5442           "Device for CIG {} and using cis_handle 0x{:04x} is disconnected.",
5443           cig_id, conn_handle);
5444       return;
5445     }
5446     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5447 
5448     instance->groupStateMachine_->ProcessHciNotifSetupIsoDataPath(
5449         group, leAudioDevice, status, conn_handle);
5450   }
5451 
IsoRemoveIsoDataPathCb(uint8_t status,uint16_t conn_handle,uint8_t cig_id)5452   void IsoRemoveIsoDataPathCb(uint8_t status, uint16_t conn_handle,
5453                               uint8_t cig_id) {
5454     LeAudioDevice* leAudioDevice =
5455         leAudioDevices_.FindByCisConnHdl(cig_id, conn_handle);
5456 
5457     /* If CIS has been disconnected just before ACL being disconnected by the
5458      * remote device, leAudioDevice might be already cleared i.e. has no
5459      * information about conn_handle, when the data path remove compete arrives.
5460      */
5461     if (!leAudioDevice) {
5462       log::warn(
5463           "Device for CIG {} and using cis_handle 0x{:04x} is disconnected.",
5464           cig_id, conn_handle);
5465       return;
5466     }
5467 
5468     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5469 
5470     instance->groupStateMachine_->ProcessHciNotifRemoveIsoDataPath(
5471         group, leAudioDevice, status, conn_handle);
5472   }
5473 
IsoLinkQualityReadCb(uint8_t conn_handle,uint8_t cig_id,uint32_t txUnackedPackets,uint32_t txFlushedPackets,uint32_t txLastSubeventPackets,uint32_t retransmittedPackets,uint32_t crcErrorPackets,uint32_t rxUnreceivedPackets,uint32_t duplicatePackets)5474   void IsoLinkQualityReadCb(
5475       uint8_t conn_handle, uint8_t cig_id, uint32_t txUnackedPackets,
5476       uint32_t txFlushedPackets, uint32_t txLastSubeventPackets,
5477       uint32_t retransmittedPackets, uint32_t crcErrorPackets,
5478       uint32_t rxUnreceivedPackets, uint32_t duplicatePackets) {
5479     LeAudioDevice* leAudioDevice =
5480         leAudioDevices_.FindByCisConnHdl(cig_id, conn_handle);
5481     if (!leAudioDevice) {
5482       log::warn(
5483           "device under connection handle: 0x{:x}, has been disconnecected in "
5484           "meantime",
5485           conn_handle);
5486       return;
5487     }
5488     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5489 
5490     instance->groupStateMachine_->ProcessHciNotifIsoLinkQualityRead(
5491         group, leAudioDevice, conn_handle, txUnackedPackets, txFlushedPackets,
5492         txLastSubeventPackets, retransmittedPackets, crcErrorPackets,
5493         rxUnreceivedPackets, duplicatePackets);
5494   }
5495 
HandlePendingDeviceRemove(LeAudioDeviceGroup * group)5496   void HandlePendingDeviceRemove(LeAudioDeviceGroup* group) {
5497     for (auto device = group->GetFirstDevice(); device != nullptr;
5498          device = group->GetNextDevice(device)) {
5499       if (device->GetConnectionState() == DeviceConnectState::REMOVING) {
5500         if (device->closing_stream_for_disconnection_) {
5501           device->closing_stream_for_disconnection_ = false;
5502           log::info("Disconnecting group id: {}, address: {}", group->group_id_,
5503                     device->address_);
5504           bool force_acl_disconnect =
5505               device->autoconnect_flag_ && group->IsEnabled();
5506           DisconnectDevice(device, force_acl_disconnect);
5507         }
5508         group_remove_node(group, device->address_, true);
5509       }
5510     }
5511   }
5512 
HandlePendingDeviceDisconnection(LeAudioDeviceGroup * group)5513   void HandlePendingDeviceDisconnection(LeAudioDeviceGroup* group) {
5514     log::debug("");
5515 
5516     auto leAudioDevice = group->GetFirstDevice();
5517     while (leAudioDevice) {
5518       if (leAudioDevice->closing_stream_for_disconnection_) {
5519         leAudioDevice->closing_stream_for_disconnection_ = false;
5520         log::debug("Disconnecting group id: {}, address: {}", group->group_id_,
5521                    leAudioDevice->address_);
5522         bool force_acl_disconnect =
5523             leAudioDevice->autoconnect_flag_ && group->IsEnabled();
5524         DisconnectDevice(leAudioDevice, force_acl_disconnect);
5525       }
5526       leAudioDevice = group->GetNextDevice(leAudioDevice);
5527     }
5528   }
5529 
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config & config,uint8_t remote_direction)5530   void UpdateAudioConfigToHal(
5531       const ::bluetooth::le_audio::offload_config& config,
5532       uint8_t remote_direction) {
5533     if ((remote_direction &
5534          bluetooth::le_audio::types::kLeAudioDirectionSink) &&
5535         le_audio_source_hal_client_) {
5536       le_audio_source_hal_client_->UpdateAudioConfigToHal(config);
5537     }
5538     if ((remote_direction &
5539          bluetooth::le_audio::types::kLeAudioDirectionSource) &&
5540         le_audio_sink_hal_client_) {
5541       le_audio_sink_hal_client_->UpdateAudioConfigToHal(config);
5542     }
5543   }
5544 
NotifyUpperLayerGroupTurnedIdleDuringCall(int group_id)5545   void NotifyUpperLayerGroupTurnedIdleDuringCall(int group_id) {
5546     if (!osi_property_get_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall,
5547                                false)) {
5548       return;
5549     }
5550 
5551     /* If group is inactive, phone is in call and Group is not having CIS
5552      * connected, notify upper layer about it, so it can decide to create SCO if
5553      * it is in the handover case
5554      */
5555     if ((IsInCall() || IsInVoipCall()) &&
5556         active_group_id_ == bluetooth::groups::kGroupUnknown) {
5557       callbacks_->OnGroupStatus(group_id, GroupStatus::TURNED_IDLE_DURING_CALL);
5558     }
5559   }
5560 
take_stream_time(void)5561   void take_stream_time(void) {
5562     if (stream_setup_start_timestamp_ == 0) {
5563       return;
5564     }
5565 
5566     if (stream_start_history_queue_.size() == 10) {
5567       stream_start_history_queue_.pop_back();
5568     }
5569 
5570     stream_setup_end_timestamp_ = bluetooth::common::time_get_os_boottime_us();
5571     stream_start_history_queue_.emplace_front(
5572         (stream_setup_end_timestamp_ - stream_setup_start_timestamp_) / 1000);
5573 
5574     stream_setup_end_timestamp_ = 0;
5575     stream_setup_start_timestamp_ = 0;
5576   }
5577 
notifyGroupStreamStatus(int group_id,GroupStreamStatus groupStreamStatus)5578   void notifyGroupStreamStatus(int group_id,
5579                                GroupStreamStatus groupStreamStatus) {
5580     if (!com::android::bluetooth::flags::
5581             leaudio_callback_on_group_stream_status()) {
5582       return;
5583     }
5584 
5585     GroupStreamStatus newGroupStreamStatus = GroupStreamStatus::IDLE;
5586     if (groupStreamStatus == GroupStreamStatus::STREAMING) {
5587       newGroupStreamStatus = GroupStreamStatus::STREAMING;
5588     }
5589 
5590     auto it = lastNotifiedGroupStreamStatusMap_.find(group_id);
5591 
5592     if (it != lastNotifiedGroupStreamStatusMap_.end()) {
5593       if (it->second != newGroupStreamStatus) {
5594         callbacks_->OnGroupStreamStatus(group_id, newGroupStreamStatus);
5595         it->second = newGroupStreamStatus;
5596       }
5597     } else {
5598       callbacks_->OnGroupStreamStatus(group_id, newGroupStreamStatus);
5599       lastNotifiedGroupStreamStatusMap_.emplace(group_id, newGroupStreamStatus);
5600     }
5601   }
5602 
handleAsymmetricPhyForUnicast(LeAudioDeviceGroup * group)5603   void handleAsymmetricPhyForUnicast(LeAudioDeviceGroup* group) {
5604     if (!group->asymmetric_phy_for_unidirectional_cis_supported) return;
5605 
5606     auto it = lastNotifiedGroupStreamStatusMap_.find(group->group_id_);
5607 
5608     if (it != lastNotifiedGroupStreamStatusMap_.end() &&
5609         it->second == GroupStreamStatus::STREAMING &&
5610         group->GetSduInterval(bluetooth::le_audio::types::kLeAudioDirectionSource) == 0) {
5611       SetAsymmetricBlePhy(group, true);
5612       return;
5613     }
5614 
5615     SetAsymmetricBlePhy(group, false);
5616   }
5617 
OnStateMachineStatusReportCb(int group_id,GroupStreamStatus status)5618   void OnStateMachineStatusReportCb(int group_id, GroupStreamStatus status) {
5619     log::info(
5620         "status: {} ,  group_id: {}, audio_sender_state {}, "
5621         "audio_receiver_state {}",
5622         static_cast<int>(status), group_id,
5623         bluetooth::common::ToString(audio_sender_state_),
5624         bluetooth::common::ToString(audio_receiver_state_));
5625     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
5626 
5627     notifyGroupStreamStatus(group_id, status);
5628 
5629     switch (status) {
5630       case GroupStreamStatus::STREAMING: {
5631         log::assert_that(group_id == active_group_id_,
5632                          "invalid group id {}!={}", group_id, active_group_id_);
5633 
5634         take_stream_time();
5635 
5636         bluetooth::le_audio::MetricsCollector::Get()->OnStreamStarted(
5637             active_group_id_, configuration_context_type_);
5638 
5639         if (leAudioHealthStatus_) {
5640           leAudioHealthStatus_->AddStatisticForGroup(
5641               group, LeAudioHealthGroupStatType::STREAM_CREATE_SUCCESS);
5642         }
5643 
5644         if (!group) {
5645           log::error("Group {} does not exist anymore. This shall not happen",
5646                      group_id);
5647           return;
5648         }
5649 
5650         handleAsymmetricPhyForUnicast(group);
5651 
5652         if ((audio_sender_state_ == AudioState::IDLE) &&
5653             (audio_receiver_state_ == AudioState::IDLE)) {
5654           /* Audio Framework is not interested in the stream anymore.
5655            * Just stop streaming
5656            */
5657           log::warn("Stopping stream for group {} as AF not interested.",
5658                     group_id);
5659           groupStateMachine_->StopStream(group);
5660           return;
5661         }
5662 
5663         /* It might happen that the configuration has already changed, while
5664          * the group was in the ongoing reconfiguration. We should stop the
5665          * stream and reconfigure once again.
5666          */
5667         if (group->GetConfigurationContextType() !=
5668             configuration_context_type_) {
5669           log::debug(
5670               "The configuration {} is no longer valid. Stopping the stream to "
5671               "reconfigure to {}",
5672               ToString(group->GetConfigurationContextType()),
5673               ToString(configuration_context_type_));
5674           group->SetPendingConfiguration();
5675           groupStateMachine_->StopStream(group);
5676           stream_setup_start_timestamp_ =
5677               bluetooth::common::time_get_os_boottime_us();
5678           return;
5679         }
5680 
5681         BidirectionalPair<uint16_t> delays_pair = {
5682             .sink = group->GetRemoteDelay(
5683                 bluetooth::le_audio::types::kLeAudioDirectionSink),
5684             .source = group->GetRemoteDelay(
5685                 bluetooth::le_audio::types::kLeAudioDirectionSource)};
5686         CodecManager::GetInstance()->UpdateActiveAudioConfig(
5687             group->stream_conf.stream_params, delays_pair,
5688             std::bind(&LeAudioClientImpl::UpdateAudioConfigToHal,
5689                       weak_factory_.GetWeakPtr(), std::placeholders::_1,
5690                       std::placeholders::_2));
5691 
5692         /* When at least one direction is started we can assume new
5693          * configuration here */
5694         bool new_configuration = false;
5695         if (audio_sender_state_ == AudioState::READY_TO_START) {
5696           StartSendingAudio(group_id);
5697           new_configuration = true;
5698         }
5699 
5700         if (audio_receiver_state_ == AudioState::READY_TO_START) {
5701           StartReceivingAudio(group_id);
5702           new_configuration = true;
5703         }
5704 
5705         if (new_configuration) {
5706           /* Notify Java about new configuration */
5707           SendAudioGroupCurrentCodecConfigChanged(group);
5708         }
5709         break;
5710       }
5711       case GroupStreamStatus::SUSPENDED:
5712         stream_setup_end_timestamp_ = 0;
5713         stream_setup_start_timestamp_ = 0;
5714         /** Stop Audio but don't release all the Audio resources */
5715         SuspendAudio();
5716         break;
5717       case GroupStreamStatus::CONFIGURED_BY_USER: {
5718         // Check which directions were suspended
5719         uint8_t previously_active_directions = 0;
5720         if (audio_sender_state_ >= AudioState::READY_TO_START) {
5721           previously_active_directions |=
5722               bluetooth::le_audio::types::kLeAudioDirectionSink;
5723         }
5724         if (audio_receiver_state_ >= AudioState::READY_TO_START) {
5725           previously_active_directions |=
5726               bluetooth::le_audio::types::kLeAudioDirectionSource;
5727         }
5728 
5729         /* We are done with reconfiguration.
5730          * Clean state and if Audio HAL is waiting, cancel the request
5731          * so Audio HAL can Resume again.
5732          */
5733         CancelStreamingRequest();
5734         ReconfigurationComplete(previously_active_directions);
5735       } break;
5736       case GroupStreamStatus::CONFIGURED_AUTONOMOUS:
5737         /* This state is notified only when
5738          * groups stays into CONFIGURED state after
5739          * STREAMING. Peer device uses cache. For the moment
5740          * it is handled same as IDLE
5741          */
5742       case GroupStreamStatus::IDLE: {
5743         if (sw_enc_left) sw_enc_left.reset();
5744         if (sw_enc_right) sw_enc_right.reset();
5745         if (sw_dec_left) sw_dec_left.reset();
5746         if (sw_dec_right) sw_dec_right.reset();
5747         CleanCachedMicrophoneData();
5748 
5749         if (group) {
5750           handleAsymmetricPhyForUnicast(group);
5751           UpdateLocationsAndContextsAvailability(group);
5752           if (group->IsPendingConfiguration()) {
5753             SuspendedForReconfiguration();
5754             auto remote_direction =
5755                 kLeAudioContextAllRemoteSource.test(configuration_context_type_)
5756                     ? bluetooth::le_audio::types::kLeAudioDirectionSource
5757                     : bluetooth::le_audio::types::kLeAudioDirectionSink;
5758 
5759             /* Reconfiguration to non requiring source scenario */
5760             if (sink_monitor_mode_ &&
5761                 (remote_direction ==
5762                  bluetooth::le_audio::types::kLeAudioDirectionSink)) {
5763               notifyAudioLocalSink(
5764                   UnicastMonitorModeStatus::STREAMING_SUSPENDED);
5765             }
5766 
5767             auto remote_contexts =
5768                 DirectionalRealignMetadataAudioContexts(group, remote_direction);
5769             ApplyRemoteMetadataAudioContextPolicy(group, remote_contexts,
5770                                                   remote_direction);
5771             if (GroupStream(group->group_id_, configuration_context_type_,
5772                             remote_contexts)) {
5773               /* If configuration succeed wait for new status. */
5774               return;
5775             }
5776             log::info("Clear pending configuration flag for group {}",
5777                       group->group_id_);
5778             group->ClearPendingConfiguration();
5779           } else {
5780             if (sink_monitor_mode_) {
5781               notifyAudioLocalSink(
5782                   UnicastMonitorModeStatus::STREAMING_SUSPENDED);
5783             }
5784 
5785             if (source_monitor_mode_) {
5786               callbacks_->OnUnicastMonitorModeStatus(
5787                   bluetooth::le_audio::types::kLeAudioDirectionSource,
5788                   UnicastMonitorModeStatus::STREAMING_SUSPENDED);
5789             }
5790           }
5791         }
5792 
5793         stream_setup_end_timestamp_ = 0;
5794         stream_setup_start_timestamp_ = 0;
5795         CancelStreamingRequest();
5796 
5797         if (group) {
5798           NotifyUpperLayerGroupTurnedIdleDuringCall(group->group_id_);
5799           HandlePendingDeviceRemove(group);
5800           HandlePendingDeviceDisconnection(group);
5801         }
5802         break;
5803       }
5804       case GroupStreamStatus::RELEASING:
5805       case GroupStreamStatus::SUSPENDING:
5806         if (active_group_id_ != bluetooth::groups::kGroupUnknown &&
5807             (active_group_id_ == group->group_id_) &&
5808             !group->IsPendingConfiguration() &&
5809             (audio_sender_state_ == AudioState::STARTED ||
5810              audio_receiver_state_ == AudioState::STARTED)) {
5811           /* If releasing state is happening but it was not initiated either by
5812            * reconfiguration or Audio Framework actions either by the Active group change,
5813            * it means that it is some internal state machine error. This is very unlikely and
5814            * for now just Inactivate the group.
5815            */
5816           log::error("Internal state machine error");
5817           group->PrintDebugState();
5818           groupSetAndNotifyInactive();
5819         }
5820 
5821         if (audio_sender_state_ != AudioState::IDLE)
5822           audio_sender_state_ = AudioState::RELEASING;
5823 
5824         if (audio_receiver_state_ != AudioState::IDLE)
5825           audio_receiver_state_ = AudioState::RELEASING;
5826 
5827         break;
5828       default:
5829         break;
5830     }
5831   }
5832 
OnUpdatedCisConfiguration(int group_id,uint8_t direction)5833   void OnUpdatedCisConfiguration(int group_id, uint8_t direction) {
5834     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
5835     if (!group) {
5836       log::error("Invalid group_id: {}", group_id);
5837       return;
5838     }
5839     group->UpdateCisConfiguration(direction);
5840   }
5841 
5842  private:
5843   tGATT_IF gatt_if_;
5844   bluetooth::le_audio::LeAudioClientCallbacks* callbacks_;
5845   LeAudioDevices leAudioDevices_;
5846   LeAudioDeviceGroups aseGroups_;
5847   LeAudioGroupStateMachine* groupStateMachine_;
5848   int active_group_id_;
5849   LeAudioContextType configuration_context_type_;
5850   static constexpr char kAllowMultipleContextsInMetadata[] =
5851       "persist.bluetooth.leaudio.allow.multiple.contexts";
5852   BidirectionalPair<AudioContexts> local_metadata_context_types_;
5853   uint64_t stream_setup_start_timestamp_;
5854   uint64_t stream_setup_end_timestamp_;
5855   std::deque<uint64_t> stream_start_history_queue_;
5856 
5857   /* Microphone (s) */
5858   AudioState audio_receiver_state_;
5859   /* Speaker(s) */
5860   AudioState audio_sender_state_;
5861   /* Keep in call state. */
5862   bool in_call_;
5863   bool in_voip_call_;
5864   /* Listen for streaming status on Sink stream */
5865   bool sink_monitor_mode_;
5866   /* Status which has been notified to Service */
5867   std::optional<UnicastMonitorModeStatus> sink_monitor_notified_status_;
5868   /* Listen for streaming status on Source stream */
5869   bool source_monitor_mode_;
5870 
5871   /* Reconnection mode */
5872   tBTM_BLE_CONN_TYPE reconnection_mode_;
5873   static constexpr uint64_t kGroupConnectedWatchDelayMs = 3000;
5874   static constexpr uint64_t kRecoveryReconnectDelayMs = 2000;
5875   static constexpr uint64_t kAutoConnectAfterOwnDisconnectDelayMs = 1000;
5876   static constexpr uint64_t kCsisGroupMemberDelayMs = 5000;
5877 
5878   /* LeAudioHealthStatus */
5879   LeAudioHealthStatus* leAudioHealthStatus_ = nullptr;
5880 
5881   static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] =
5882       "persist.bluetooth.leaudio.notify.idle.during.call";
5883 
5884   static constexpr uint16_t kBapMinimumAttMtu = 64;
5885 
5886   /* Current stream configuration - used to set up the software codecs */
5887   LeAudioCodecConfiguration current_encoder_config_;
5888   LeAudioCodecConfiguration current_decoder_config_;
5889 
5890   /* Static Audio Framework session configuration.
5891    *  Resampling will be done inside the bt stack
5892    */
5893   LeAudioCodecConfiguration audio_framework_source_config = {
5894       .num_channels = 2,
5895       .sample_rate = bluetooth::audio::le_audio::kSampleRate48000,
5896       .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
5897       .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
5898   };
5899 
5900   LeAudioCodecConfiguration audio_framework_sink_config = {
5901       .num_channels = 2,
5902       .sample_rate = bluetooth::audio::le_audio::kSampleRate16000,
5903       .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
5904       .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
5905   };
5906 
5907   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_enc_left;
5908   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_enc_right;
5909 
5910   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_dec_left;
5911   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_dec_right;
5912 
5913   std::vector<uint8_t> encoded_data;
5914   std::unique_ptr<LeAudioSourceAudioHalClient> le_audio_source_hal_client_;
5915   std::unique_ptr<LeAudioSinkAudioHalClient> le_audio_sink_hal_client_;
5916   static constexpr uint64_t kAudioSuspentKeepIsoAliveTimeoutMs = 5000;
5917   static constexpr uint64_t kAudioDisableTimeoutMs = 3000;
5918   static constexpr char kAudioSuspentKeepIsoAliveTimeoutMsProp[] =
5919       "persist.bluetooth.leaudio.audio.suspend.timeoutms";
5920   alarm_t* close_vbc_timeout_;
5921   alarm_t* suspend_timeout_;
5922   alarm_t* disable_timer_;
5923   static constexpr uint64_t kDeviceAttachDelayMs = 500;
5924 
5925   uint32_t cached_channel_timestamp_ = 0;
5926   bluetooth::le_audio::CodecInterface* cached_channel_ = nullptr;
5927 
5928   base::WeakPtrFactory<LeAudioClientImpl> weak_factory_{this};
5929 
5930   std::map<int, GroupStreamStatus> lastNotifiedGroupStreamStatusMap_;
5931 
ClientAudioInterfaceRelease()5932   void ClientAudioInterfaceRelease() {
5933     auto group = aseGroups_.FindById(active_group_id_);
5934     if (!group) {
5935       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
5936     } else {
5937       handleAsymmetricPhyForUnicast(group);
5938       log::info("ClientAudioInterfaceRelease - cleanup");
5939     }
5940 
5941     auto result =
5942         CodecManager::GetInstance()->UpdateActiveUnicastAudioHalClient(
5943             le_audio_source_hal_client_.get(), le_audio_sink_hal_client_.get(),
5944             false);
5945     log::assert_that(result, "Could not update session to codec manager");
5946 
5947     if (le_audio_source_hal_client_) {
5948       le_audio_source_hal_client_->Stop();
5949       le_audio_source_hal_client_.reset();
5950     }
5951 
5952     if (le_audio_sink_hal_client_) {
5953       /* Keep session set up to monitor streaming request. This is required if
5954        * there is another LE Audio device streaming (e.g. Broadcast) and via
5955        * the session callbacks special action from this Module would be
5956        * required e.g. to Unicast handover.
5957        */
5958       if (!sink_monitor_mode_) {
5959         local_metadata_context_types_.sink.clear();
5960         le_audio_sink_hal_client_->Stop();
5961         le_audio_sink_hal_client_.reset();
5962       }
5963     }
5964     local_metadata_context_types_.source.clear();
5965     configuration_context_type_ = LeAudioContextType::UNINITIALIZED;
5966 
5967     bluetooth::le_audio::MetricsCollector::Get()->OnStreamEnded(
5968         active_group_id_);
5969   }
5970 
DsaDataConsume(bluetooth::hci::iso_manager::cis_data_evt * event)5971   bool DsaDataConsume(bluetooth::hci::iso_manager::cis_data_evt* event) {
5972     if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
5973       return false;
5974     }
5975 
5976     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
5977       return false;
5978     }
5979     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
5980     if (!group || !group->dsa_.active) {
5981       return false;
5982     }
5983 
5984     if (group->dsa_.mode != DsaMode::ISO_SW) {
5985       log::warn("ISO packets received over HCI in DSA mode: {}",
5986                 group->dsa_.mode);
5987       return false;
5988     }
5989 
5990     if (iso_data_callback == nullptr) {
5991       log::warn("Dsa data consumer not registered");
5992       return false;
5993     }
5994 
5995     uint16_t cis_conn_hdl = event->cis_conn_hdl;
5996     uint8_t* data = event->p_msg->data + event->p_msg->offset;
5997     uint16_t size = event->p_msg->len - event->p_msg->offset;
5998     uint32_t timestamp = event->ts;
5999 
6000     // Find LE Audio device
6001     LeAudioDevice* leAudioDevice = group->GetFirstDevice();
6002     while (leAudioDevice != nullptr) {
6003       if (leAudioDevice->GetDsaCisHandle() == cis_conn_hdl &&
6004           leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURED) {
6005         break;
6006       }
6007       leAudioDevice = group->GetNextDevice(leAudioDevice);
6008     }
6009     if (leAudioDevice == nullptr) {
6010       log::warn("No LE Audio device found for CIS handle: {}", cis_conn_hdl);
6011       return false;
6012     }
6013 
6014     bool consumed = iso_data_callback(leAudioDevice->address_, cis_conn_hdl,
6015                                       data, size, timestamp);
6016     if (consumed) {
6017       return true;
6018     } else {
6019       log::verbose("ISO data consumer not ready to accept data");
6020       return false;
6021     }
6022   }
6023 
SetAsymmetricBlePhy(LeAudioDeviceGroup * group,bool asymmetric)6024   void SetAsymmetricBlePhy(LeAudioDeviceGroup* group, bool asymmetric) {
6025     LeAudioDevice* leAudioDevice = group->GetFirstDevice();
6026     if (leAudioDevice == nullptr) {
6027       log::error("Shouldn't be called without a device.");
6028       return;
6029     }
6030 
6031     for (auto tmpDevice = leAudioDevice; tmpDevice != nullptr;
6032          tmpDevice = group->GetNextDevice(tmpDevice)) {
6033       log::info(
6034           "tmpDevice->acl_asymmetric_: {}, asymmetric: {}, address: {}, "
6035           "acl_connected: {}",
6036           tmpDevice->acl_asymmetric_ == asymmetric, asymmetric,
6037           tmpDevice->address_,
6038           BTM_IsAclConnectionUp(tmpDevice->address_, BT_TRANSPORT_LE));
6039       if (tmpDevice->acl_asymmetric_ == asymmetric ||
6040           !BTM_IsAclConnectionUp(tmpDevice->address_, BT_TRANSPORT_LE))
6041         continue;
6042 
6043       log::info("SetAsymmetricBlePhy: {} for {}", asymmetric,
6044                 tmpDevice->address_);
6045       BTM_BleSetPhy(tmpDevice->address_, PHY_LE_2M,
6046                     asymmetric ? PHY_LE_1M : PHY_LE_2M, 0);
6047       tmpDevice->acl_asymmetric_ = asymmetric;
6048     }
6049   }
6050 };
6051 
le_audio_health_status_callback(const RawAddress & addr,int group_id,LeAudioHealthBasedAction action)6052 static void le_audio_health_status_callback(const RawAddress& addr,
6053                                             int group_id,
6054                                             LeAudioHealthBasedAction action) {
6055   if (instance) {
6056     instance->LeAudioHealthSendRecommendation(addr, group_id, action);
6057   }
6058 }
6059 
6060 /* This is a generic callback method for gatt client which handles every client
6061  * application events.
6062  */
le_audio_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)6063 void le_audio_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
6064   if (!p_data || !instance) return;
6065 
6066   log::info("event = {}", static_cast<int>(event));
6067 
6068   switch (event) {
6069     case BTA_GATTC_DEREG_EVT:
6070       break;
6071 
6072     case BTA_GATTC_NOTIF_EVT:
6073       instance->LeAudioCharValueHandle(
6074           p_data->notify.conn_id, p_data->notify.handle, p_data->notify.len,
6075           static_cast<uint8_t*>(p_data->notify.value), true);
6076 
6077       if (!p_data->notify.is_notify)
6078         BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);
6079 
6080       break;
6081 
6082     case BTA_GATTC_OPEN_EVT:
6083       instance->OnGattConnected(p_data->open.status, p_data->open.conn_id,
6084                                 p_data->open.client_if, p_data->open.remote_bda,
6085                                 p_data->open.transport, p_data->open.mtu);
6086       break;
6087 
6088     case BTA_GATTC_ENC_CMPL_CB_EVT: {
6089       uint8_t encryption_status;
6090       if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) {
6091         encryption_status = BTM_SUCCESS;
6092       } else {
6093         encryption_status = BTM_FAILED_ON_SECURITY;
6094       }
6095       instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda,
6096                                      encryption_status);
6097     } break;
6098 
6099     case BTA_GATTC_CLOSE_EVT:
6100       instance->OnGattDisconnected(
6101           p_data->close.conn_id, p_data->close.client_if,
6102           p_data->close.remote_bda, p_data->close.reason);
6103       break;
6104 
6105     case BTA_GATTC_SEARCH_CMPL_EVT:
6106       instance->OnServiceSearchComplete(p_data->search_cmpl.conn_id,
6107                                         p_data->search_cmpl.status);
6108       break;
6109 
6110     case BTA_GATTC_SRVC_DISC_DONE_EVT:
6111       instance->OnGattServiceDiscoveryDone(p_data->service_changed.remote_bda);
6112       break;
6113 
6114     case BTA_GATTC_SRVC_CHG_EVT:
6115       instance->OnServiceChangeEvent(p_data->remote_bda);
6116       break;
6117     case BTA_GATTC_CFG_MTU_EVT:
6118       instance->OnMtuChanged(p_data->cfg_mtu.conn_id, p_data->cfg_mtu.mtu);
6119       break;
6120     case BTA_GATTC_PHY_UPDATE_EVT:
6121       instance->OnPhyUpdate(
6122           p_data->phy_update.conn_id, p_data->phy_update.tx_phy,
6123           p_data->phy_update.rx_phy, p_data->phy_update.status);
6124       break;
6125     default:
6126       break;
6127   }
6128 }
6129 
6130 class LeAudioStateMachineHciCallbacksImpl : public CigCallbacks {
6131  public:
OnCigEvent(uint8_t event,void * data)6132   void OnCigEvent(uint8_t event, void* data) override {
6133     if (instance) instance->IsoCigEventsCb(event, data);
6134   }
6135 
OnCisEvent(uint8_t event,void * data)6136   void OnCisEvent(uint8_t event, void* data) override {
6137     if (instance) instance->IsoCisEventsCb(event, data);
6138   }
6139 
OnSetupIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t cig_id)6140   void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle,
6141                           uint8_t cig_id) override {
6142     if (instance) instance->IsoSetupIsoDataPathCb(status, conn_handle, cig_id);
6143   }
6144 
OnRemoveIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t cig_id)6145   void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle,
6146                            uint8_t cig_id) override {
6147     if (instance) instance->IsoRemoveIsoDataPathCb(status, conn_handle, cig_id);
6148   }
6149 
OnIsoLinkQualityRead(uint8_t conn_handle,uint8_t cig_id,uint32_t txUnackedPackets,uint32_t txFlushedPackets,uint32_t txLastSubeventPackets,uint32_t retransmittedPackets,uint32_t crcErrorPackets,uint32_t rxUnreceivedPackets,uint32_t duplicatePackets)6150   void OnIsoLinkQualityRead(
6151       uint8_t conn_handle, uint8_t cig_id, uint32_t txUnackedPackets,
6152       uint32_t txFlushedPackets, uint32_t txLastSubeventPackets,
6153       uint32_t retransmittedPackets, uint32_t crcErrorPackets,
6154       uint32_t rxUnreceivedPackets, uint32_t duplicatePackets) {
6155     if (instance)
6156       instance->IsoLinkQualityReadCb(conn_handle, cig_id, txUnackedPackets,
6157                                      txFlushedPackets, txLastSubeventPackets,
6158                                      retransmittedPackets, crcErrorPackets,
6159                                      rxUnreceivedPackets, duplicatePackets);
6160   }
6161 };
6162 
6163 LeAudioStateMachineHciCallbacksImpl stateMachineHciCallbacksImpl;
6164 
6165 class CallbacksImpl : public LeAudioGroupStateMachine::Callbacks {
6166  public:
StatusReportCb(int group_id,GroupStreamStatus status)6167   void StatusReportCb(int group_id, GroupStreamStatus status) override {
6168     if (instance) instance->OnStateMachineStatusReportCb(group_id, status);
6169   }
6170 
OnStateTransitionTimeout(int group_id)6171   void OnStateTransitionTimeout(int group_id) override {
6172     if (instance) instance->OnLeAudioDeviceSetStateTimeout(group_id);
6173   }
6174 
OnDeviceAutonomousStateTransitionTimeout(LeAudioDevice * leAudioDevice)6175   void OnDeviceAutonomousStateTransitionTimeout(
6176       LeAudioDevice* leAudioDevice) override {
6177     if (instance)
6178       instance->OnDeviceAutonomousStateTransitionTimeout(leAudioDevice);
6179   }
6180 
OnUpdatedCisConfiguration(int group_id,uint8_t direction)6181   void OnUpdatedCisConfiguration(int group_id, uint8_t direction) {
6182     if (instance) instance->OnUpdatedCisConfiguration(group_id, direction);
6183   }
6184 };
6185 
6186 CallbacksImpl stateMachineCallbacksImpl;
6187 
6188 class SourceCallbacksImpl : public LeAudioSourceAudioHalClient::Callbacks {
6189  public:
OnAudioDataReady(const std::vector<uint8_t> & data)6190   void OnAudioDataReady(const std::vector<uint8_t>& data) override {
6191     if (instance) instance->OnAudioDataReady(data);
6192   }
OnAudioSuspend(void)6193   void OnAudioSuspend(void) override {
6194     if (instance) instance->OnLocalAudioSourceSuspend();
6195   }
6196 
OnAudioResume(void)6197   void OnAudioResume(void) override {
6198     if (instance) instance->OnLocalAudioSourceResume();
6199   }
6200 
OnAudioMetadataUpdate(std::vector<struct playback_track_metadata_v7> source_metadata,DsaMode dsa_mode)6201   void OnAudioMetadataUpdate(
6202       std::vector<struct playback_track_metadata_v7> source_metadata,
6203       DsaMode dsa_mode) override {
6204     if (instance)
6205       instance->OnLocalAudioSourceMetadataUpdate(source_metadata, dsa_mode);
6206   }
6207 };
6208 
6209 class SinkCallbacksImpl : public LeAudioSinkAudioHalClient::Callbacks {
6210  public:
OnAudioSuspend(void)6211   void OnAudioSuspend(void) override {
6212     if (instance) instance->OnLocalAudioSinkSuspend();
6213   }
OnAudioResume(void)6214   void OnAudioResume(void) override {
6215     if (instance) instance->OnLocalAudioSinkResume();
6216   }
6217 
OnAudioMetadataUpdate(std::vector<record_track_metadata_v7> sink_metadata)6218   void OnAudioMetadataUpdate(
6219       std::vector<record_track_metadata_v7> sink_metadata) override {
6220     if (instance) instance->OnLocalAudioSinkMetadataUpdate(sink_metadata);
6221   }
6222 };
6223 
6224 SourceCallbacksImpl audioSinkReceiverImpl;
6225 SinkCallbacksImpl audioSourceReceiverImpl;
6226 
6227 class DeviceGroupsCallbacksImpl : public DeviceGroupsCallbacks {
6228  public:
OnGroupAdded(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)6229   void OnGroupAdded(const RawAddress& address, const bluetooth::Uuid& uuid,
6230                     int group_id) override {
6231     if (instance) instance->OnGroupAddedCb(address, uuid, group_id);
6232   }
OnGroupMemberAdded(const RawAddress & address,int group_id)6233   void OnGroupMemberAdded(const RawAddress& address, int group_id) override {
6234     if (instance) instance->OnGroupMemberAddedCb(address, group_id);
6235   }
OnGroupMemberRemoved(const RawAddress & address,int group_id)6236   void OnGroupMemberRemoved(const RawAddress& address, int group_id) override {
6237     if (instance) instance->OnGroupMemberRemovedCb(address, group_id);
6238   }
OnGroupRemoved(const bluetooth::Uuid & uuid,int group_id)6239   void OnGroupRemoved(const bluetooth::Uuid& uuid, int group_id) {
6240     /* to implement if needed */
6241   }
OnGroupAddFromStorage(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)6242   void OnGroupAddFromStorage(const RawAddress& address,
6243                              const bluetooth::Uuid& uuid, int group_id) {
6244     /* to implement if needed */
6245   }
6246 };
6247 
6248 class DeviceGroupsCallbacksImpl;
6249 DeviceGroupsCallbacksImpl deviceGroupsCallbacksImpl;
6250 
6251 }  // namespace
6252 
AddFromStorage(const RawAddress & addr,bool autoconnect,int sink_audio_location,int source_audio_location,int sink_supported_context_types,int source_supported_context_types,const std::vector<uint8_t> & handles,const std::vector<uint8_t> & sink_pacs,const std::vector<uint8_t> & source_pacs,const std::vector<uint8_t> & ases)6253 void LeAudioClient::AddFromStorage(
6254     const RawAddress& addr, bool autoconnect, int sink_audio_location,
6255     int source_audio_location, int sink_supported_context_types,
6256     int source_supported_context_types, const std::vector<uint8_t>& handles,
6257     const std::vector<uint8_t>& sink_pacs,
6258     const std::vector<uint8_t>& source_pacs, const std::vector<uint8_t>& ases) {
6259   if (!instance) {
6260     log::error("Not initialized yet");
6261     return;
6262   }
6263 
6264   instance->AddFromStorage(addr, autoconnect, sink_audio_location,
6265                            source_audio_location, sink_supported_context_types,
6266                            source_supported_context_types, handles, sink_pacs,
6267                            source_pacs, ases);
6268 }
6269 
GetHandlesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6270 bool LeAudioClient::GetHandlesForStorage(const RawAddress& addr,
6271                                          std::vector<uint8_t>& out) {
6272   if (!instance) {
6273     log::error("Not initialized yet");
6274     return false;
6275   }
6276 
6277   return instance->GetHandlesForStorage(addr, out);
6278 }
6279 
GetSinkPacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6280 bool LeAudioClient::GetSinkPacsForStorage(const RawAddress& addr,
6281                                           std::vector<uint8_t>& out) {
6282   if (!instance) {
6283     log::error("Not initialized yet");
6284     return false;
6285   }
6286 
6287   return instance->GetSinkPacsForStorage(addr, out);
6288 }
6289 
GetSourcePacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6290 bool LeAudioClient::GetSourcePacsForStorage(const RawAddress& addr,
6291                                             std::vector<uint8_t>& out) {
6292   if (!instance) {
6293     log::error("Not initialized yet");
6294     return false;
6295   }
6296 
6297   return instance->GetSourcePacsForStorage(addr, out);
6298 }
6299 
GetAsesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6300 bool LeAudioClient::GetAsesForStorage(const RawAddress& addr,
6301                                       std::vector<uint8_t>& out) {
6302   if (!instance) {
6303     log::error("Not initialized yet");
6304     return false;
6305   }
6306 
6307   return instance->GetAsesForStorage(addr, out);
6308 }
6309 
IsLeAudioClientRunning(void)6310 bool LeAudioClient::IsLeAudioClientRunning(void) { return instance != nullptr; }
6311 
IsLeAudioClientInStreaming(void)6312 bool LeAudioClient::IsLeAudioClientInStreaming(void) {
6313   if (!instance) {
6314     return false;
6315   }
6316   return instance->IsInStreaming();
6317 }
6318 
Get()6319 LeAudioClient* LeAudioClient::Get() {
6320   log::assert_that(instance != nullptr, "assert failed: instance != nullptr");
6321   return instance;
6322 }
6323 
6324 /* Initializer of main le audio implementation class and its instance */
Initialize(bluetooth::le_audio::LeAudioClientCallbacks * callbacks_,base::Closure initCb,base::Callback<bool ()> hal_2_1_verifier,const std::vector<bluetooth::le_audio::btle_audio_codec_config_t> & offloading_preference)6325 void LeAudioClient::Initialize(
6326     bluetooth::le_audio::LeAudioClientCallbacks* callbacks_,
6327     base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
6328     const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
6329         offloading_preference) {
6330   std::scoped_lock<std::mutex> lock(instance_mutex);
6331   if (instance) {
6332     log::error("Already initialized");
6333     return;
6334   }
6335 
6336   if (!bluetooth::shim::GetController()
6337            ->SupportsBleConnectedIsochronousStreamCentral() &&
6338       !bluetooth::shim::GetController()
6339            ->SupportsBleConnectedIsochronousStreamPeripheral()) {
6340     log::error(
6341         "Controller reports no ISO support. LeAudioClient Init aborted.");
6342     return;
6343   }
6344 
6345   log::assert_that(
6346       std::move(hal_2_1_verifier).Run(),
6347       "LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
6348       "disable LE Audio Profile, or update your HAL");
6349 
6350   IsoManager::GetInstance()->Start();
6351 
6352   audioSinkReceiver = &audioSinkReceiverImpl;
6353   audioSourceReceiver = &audioSourceReceiverImpl;
6354   stateMachineHciCallbacks = &stateMachineHciCallbacksImpl;
6355   stateMachineCallbacks = &stateMachineCallbacksImpl;
6356   device_group_callbacks = &deviceGroupsCallbacksImpl;
6357   instance = new LeAudioClientImpl(callbacks_, stateMachineCallbacks, initCb);
6358 
6359   IsoManager::GetInstance()->RegisterCigCallbacks(stateMachineHciCallbacks);
6360   CodecManager::GetInstance()->Start(offloading_preference);
6361   ContentControlIdKeeper::GetInstance()->Start();
6362 
6363   callbacks_->OnInitialized();
6364 
6365   auto cm = CodecManager::GetInstance();
6366   callbacks_->OnAudioLocalCodecCapabilities(cm->GetLocalAudioInputCodecCapa(),
6367                                             cm->GetLocalAudioOutputCodecCapa());
6368 }
6369 
DebugDump(int fd)6370 void LeAudioClient::DebugDump(int fd) {
6371   std::scoped_lock<std::mutex> lock(instance_mutex);
6372   DeviceGroups::DebugDump(fd);
6373 
6374   dprintf(fd, "LeAudio Manager: \n");
6375   if (instance)
6376     instance->Dump(fd);
6377   else
6378     dprintf(fd, "  Not initialized \n");
6379 
6380   LeAudioSinkAudioHalClient::DebugDump(fd);
6381   LeAudioSourceAudioHalClient::DebugDump(fd);
6382   bluetooth::le_audio::AudioSetConfigurationProvider::DebugDump(fd);
6383   IsoManager::GetInstance()->Dump(fd);
6384   LeAudioLogHistory::DebugDump(fd);
6385   dprintf(fd, "\n");
6386 }
6387 
Cleanup(void)6388 void LeAudioClient::Cleanup(void) {
6389   std::scoped_lock<std::mutex> lock(instance_mutex);
6390   if (!instance) {
6391     log::error("Not initialized");
6392     return;
6393   }
6394 
6395   LeAudioClientImpl* ptr = instance;
6396   instance = nullptr;
6397   ptr->Cleanup();
6398   delete ptr;
6399   ptr = nullptr;
6400 
6401   CodecManager::GetInstance()->Stop();
6402   ContentControlIdKeeper::GetInstance()->Stop();
6403   LeAudioGroupStateMachine::Cleanup();
6404 
6405   if (!LeAudioBroadcaster::IsLeAudioBroadcasterRunning())
6406     IsoManager::GetInstance()->Stop();
6407 
6408   bluetooth::le_audio::MetricsCollector::Get()->Flush();
6409 }
6410 
RegisterIsoDataConsumer(LeAudioIsoDataCallback callback)6411 bool LeAudioClient::RegisterIsoDataConsumer(LeAudioIsoDataCallback callback) {
6412   if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
6413     return false;
6414   }
6415 
6416   log::info("ISO data consumer changed");
6417   iso_data_callback = callback;
6418   return true;
6419 }
6420