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