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, ¤t_source_codec_config,
1079 ¤t_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 = ¤t_source_codec_config;
3092 dprintf(fd, " Speaker codec config (Bluetooth)\n");
3093 if (conf) {
3094 printSingleConfiguration(fd, conf, true, true);
3095 }
3096
3097 conf = ¤t_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