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