1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "a2dp_profile_peer.h"
17 #include <cstring>
18 #include "a2dp_avdtp.h"
19 #include "a2dp_codec_thread.h"
20 #include "a2dp_service.h"
21 #include "adapter_config.h"
22 #include "log.h"
23 #include "power_manager.h"
24 #include "profile_config.h"
25 #include "raw_address.h"
26 #include "securec.h"
27 #include "stub/a2dp_data_service.h"
28
29 using namespace stub;
30
31 namespace OHOS {
32 namespace bluetooth {
33 const int CODEC_BIT_MOVE8 = 8;
34 const int CODEC_BIT_MOVE16 = 16;
35 const int CODEC_SBC_SAMPLE_INDEX = 3;
36 const int CODEC_AAC_SAMPLE4 = 4;
37 const int CODEC_AAC_SAMPLE5 = 5;
38 const int CODEC_AAC_BIT6 = 6;
39 const int CODEC_AAC_BIT7 = 7;
40 const int CODEC_AAC_BIT8 = 8;
41 const int PRIORITY_DEFAULT = 1000;
42 const int CODEC_INFO_LEN = 10;
43 const int A2DP_PEER_3MB = 2;
44 std::recursive_mutex g_peerMutex {};
A2dpStream()45 A2dpStream::A2dpStream()
46 {
47 LOG_INFO("[A2dpStream] %{public}s\n", __func__);
48 (void)memset_s(&codecInfo_, sizeof(CodecInfo), 0, sizeof(CodecInfo));
49 }
50
~A2dpStream()51 A2dpStream::~A2dpStream()
52 {
53 LOG_INFO("[A2dpStream] %{public}s\n", __func__);
54 }
55
SetHandle(uint16_t hdl)56 void A2dpStream::SetHandle(uint16_t hdl)
57 {
58 LOG_INFO("[A2dpStream] %{public}s handle_(%u)\n", __func__, hdl);
59 handle_ = hdl;
60 }
61
GetHandle() const62 uint16_t A2dpStream::GetHandle() const
63 {
64 LOG_INFO("[A2dpStream] %{public}s handle_(%u)\n", __func__, handle_);
65 return handle_;
66 }
67
GetPeerSEPInformation() const68 AvdtSepConfig A2dpStream::GetPeerSEPInformation() const
69 {
70 LOG_INFO("[A2dpStream] %{public}s\n", __func__);
71 return peerCapability_;
72 }
73
SetPeerCapability(AvdtSepConfig cap)74 void A2dpStream::SetPeerCapability(AvdtSepConfig cap)
75 {
76 LOG_INFO("[A2dpStream] %{public}s\n", __func__);
77 (void)memcpy_s(&peerCapability_, sizeof(AvdtSepConfig), &cap, sizeof(AvdtSepConfig));
78 }
79
SetCodecInfo(CodecInfo data)80 void A2dpStream::SetCodecInfo(CodecInfo data)
81 {
82 LOG_INFO("[A2dpStream] %{public}s index(%u)\n", __func__, data.codecIndex);
83 (void)memcpy_s(&codecInfo_, sizeof(CodecInfo), &data, sizeof(CodecInfo));
84 }
85
GetCodecInfo() const86 CodecInfo A2dpStream::GetCodecInfo() const
87 {
88 LOG_INFO("[A2dpStream] %{public}s index(%u)\n", __func__, codecInfo_.codecIndex);
89 return codecInfo_;
90 }
91
GetAcpSeid() const92 uint8_t A2dpStream::GetAcpSeid() const
93 {
94 LOG_INFO("[A2dpStream] %{public}s acpseid(%u)\n", __func__, acpSeid_);
95 return acpSeid_;
96 }
97
SetPeerCap(bool value)98 void A2dpStream::SetPeerCap(bool value)
99 {
100 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
101 LOG_INFO("[A2dpStream] %{public}s peerCap(%{public}d)\n", __func__, value);
102 peerCap_ = value;
103 }
104
GetPeerCap() const105 bool A2dpStream::GetPeerCap() const
106 {
107 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
108 LOG_INFO("[A2dpStream] %{public}s peerCap(%{public}d)\n", __func__, peerCap_);
109 return peerCap_;
110 }
111
SetAcpSeid(uint8_t seid)112 void A2dpStream::SetAcpSeid(uint8_t seid)
113 {
114 LOG_INFO("[A2dpStream] %{public}s acpseid(%u)\n", __func__, seid);
115 acpSeid_ = seid;
116 }
117
DataAvailable(uint8_t * buf,uint32_t size)118 void A2dpCodecDecoderObserver::DataAvailable(uint8_t *buf, uint32_t size)
119 {
120 LOG_INFO("[A2dpCodecDecoderObserver] %{public}s )\n", __func__);
121 /// Read encoder data
122 stub::A2dpService::GetInstance()->setPCMStream((char *)buf, size);
123 }
124
A2dpProfilePeer(const BtAddr & addr,uint8_t localRole)125 A2dpProfilePeer::A2dpProfilePeer(const BtAddr &addr, uint8_t localRole)
126 {
127 A2dpProfilePeerInit(const_cast<BtAddr &>(addr), localRole);
128
129 return;
130 }
131
A2dpProfilePeerInit(const BtAddr & addr,const uint8_t localRole)132 void A2dpProfilePeer::A2dpProfilePeerInit(const BtAddr &addr, const uint8_t localRole)
133 {
134 LOG_INFO("[A2dpProfilePeer] %{public}s localRole(%u)\n", __func__, localRole);
135
136 localRole_ = localRole;
137 sourceStreamNum_ = 0;
138 sinkStreamNum_ = 0;
139 peerAddress_ = addr;
140 CreateDefaultCodecPriority();
141 RegisterSEPConfigureInfo(addr, localRole);
142
143 auto callbackFunc = std::bind(&A2dpProfilePeer::SignalingTimeoutCallback, this, localRole_);
144 signalingTimer_ = std::make_unique<utility::Timer>(callbackFunc);
145 auto factoryInstance = std::make_unique<A2dpCodecFactory>(defaultCodecPriorities_);
146 codecConfig_ = factoryInstance.release();
147 }
148
RegisterSEPConfigureInfo(const BtAddr & addr,uint8_t role)149 void A2dpProfilePeer::RegisterSEPConfigureInfo(const BtAddr &addr, uint8_t role)
150 {
151 uint16_t hdl = 0;
152 AvdtStreamConfig cfg = {};
153 A2dpAvdtp avdtp(role);
154 CodecInfo codecData = {};
155 cfg.cfg.mediaType = A2DP_MEDIA_TYPE_AUDIO;
156 uint8_t *codecInfo = cfg.cfg.codecInfo;
157 (void)memset_s(&codecData, sizeof(CodecInfo), 0, sizeof(CodecInfo));
158
159 if (role == A2DP_ROLE_SOURCE) {
160 for (int i = A2DP_SOURCE_CODEC_INDEX_SBC; i < A2DP_SOURCE_CODEC_INDEX_MAX; i++) {
161 int value = 0x01;
162 if (i == A2DP_SOURCE_CODEC_INDEX_SBC) {
163 AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SRC_SERVICE, PROPERTY_CODEC_SBC_SUPPORT, value);
164 LOG_INFO("[A2dpProfilePeer] %{public}s SBC value[%{public}d] \n", __func__, value);
165 if (value) {
166 A2dpProfile::BuildCodecInfo(A2DP_SOURCE_CODEC_INDEX_SBC, codecInfo);
167 } else {
168 continue;
169 }
170 } else if (i == A2DP_SOURCE_CODEC_INDEX_AAC && codecAACConfig) {
171 AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SRC_SERVICE, PROPERTY_CODEC_AAC_SUPPORT, value);
172 LOG_INFO("[A2dpProfilePeer] %{public}s AAC value[%{public}d] \n", __func__, value);
173 if (value) {
174 A2dpProfile::BuildCodecInfo(A2DP_SOURCE_CODEC_INDEX_AAC, codecInfo);
175 } else {
176 continue;
177 }
178 } else {
179 LOG_INFO("[A2dpProfilePeer] %{public}s AAC configure[%{public}d] \n", __func__, codecAACConfig);
180 break;
181 }
182 cfg.codecIndex = i;
183 avdtp.CreateStream(const_cast<BtAddr &>(addr), cfg.codecIndex, hdl);
184 streamCtrl_[i - 1].SetHandle(hdl);
185 codecData.codecIndex = static_cast<A2dpCodecIndex>(i);
186 (void)memcpy_s(codecData.codecInfo, A2DP_CODEC_SIZE, cfg.cfg.codecInfo, A2DP_CODEC_SIZE);
187 streamCtrl_[i - 1].SetCodecInfo(codecData);
188 sourceStreamNum_++;
189 }
190 } else {
191 for (int i = 0; i < (A2DP_CODEC_INDEX_MAX - A2DP_SINK_CODEC_INDEX_MIN); i++) {
192 int value = 0x01;
193 if ((i + A2DP_SINK_CODEC_INDEX_MIN) == A2DP_SINK_CODEC_INDEX_SBC) {
194 AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SNK_SERVICE, PROPERTY_CODEC_SBC_SUPPORT, value);
195 LOG_INFO("[A2dpProfilePeer] %{public}s sink SBC value[%{public}d] \n", __func__, value);
196 if (value) {
197 A2dpProfile::BuildCodecInfo(A2DP_SINK_CODEC_INDEX_SBC, codecInfo);
198 } else {
199 continue;
200 }
201 } else if ((i + A2DP_SINK_CODEC_INDEX_MIN) == A2DP_SINK_CODEC_INDEX_AAC && codecAACConfig) {
202 AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SNK_SERVICE, PROPERTY_CODEC_AAC_SUPPORT, value);
203 LOG_INFO("[A2dpProfilePeer] %{public}s sink AAC value[%{public}d] \n", __func__, value);
204 if (value) {
205 A2dpProfile::BuildCodecInfo(A2DP_SINK_CODEC_INDEX_AAC, codecInfo);
206 } else {
207 continue;
208 }
209 } else {
210 LOG_INFO("[A2dpProfilePeer] %{public}s AAC configure[%{public}d] \n", __func__, codecAACConfig);
211 break;
212 }
213 cfg.codecIndex = i + A2DP_SINK_CODEC_INDEX_MIN;
214 avdtp.CreateStream(const_cast<BtAddr &>(addr), cfg.codecIndex, hdl);
215 streamCtrl_[i].SetHandle(hdl);
216 codecData.codecIndex = static_cast<A2dpCodecIndex>(i + A2DP_SINK_CODEC_INDEX_MIN);
217 (void)memcpy_s(codecData.codecInfo, A2DP_CODEC_SIZE, cfg.cfg.codecInfo, A2DP_CODEC_SIZE);
218 streamCtrl_[i].SetCodecInfo(codecData);
219 sinkStreamNum_++;
220 }
221 }
222 LOG_INFO("[A2dpProfilePeer] %{public}s handle[%u] \n", __func__, GetIntSeid());
223 }
224
~A2dpProfilePeer()225 A2dpProfilePeer::~A2dpProfilePeer()
226 {
227 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
228
229 if (codecConfig_ != nullptr) {
230 delete codecConfig_;
231 }
232 }
233
SetPeerSepInfo(AvdtDiscover seps)234 void A2dpProfilePeer::SetPeerSepInfo(AvdtDiscover seps)
235 {
236 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
237
238 for (int i = 0; i < seps.numSeps; i++) {
239 peerSepInfo_[i].isUsed = (seps.seps[i]).isUsed;
240 peerSepInfo_[i].mediaType = (seps.seps[i]).mediaType;
241 peerSepInfo_[i].seid = (seps.seps[i]).seid;
242 peerSepInfo_[i].sepType = (seps.seps[i]).sepType;
243 LOG_INFO("[A2dpProfilePeer]%{public}s i[%{public}d] acpid[%u] sepNum[%u] septype[%u]\n",
244 __func__,
245 i,
246 peerSepInfo_[i].seid,
247 seps.numSeps,
248 peerSepInfo_[i].sepType);
249 }
250
251 peerNumSeps_ = seps.numSeps;
252 peerSepIndex_ = 0;
253 }
254
SetPeerCapInfo(uint8_t intSeid,uint8_t acpSeid,AvdtSepConfig cap,uint8_t role)255 bool A2dpProfilePeer::SetPeerCapInfo(uint8_t intSeid, uint8_t acpSeid, AvdtSepConfig cap, uint8_t role)
256 {
257 bool ret = false;
258 uint8_t *codecInfo = cap.codecInfo;
259
260 /// save peer capability
261 if (role == A2DP_ROLE_SOURCE) {
262 // check valid
263 if (!IsPeerSinkCodecValid(codecInfo)) {
264 LOG_ERROR("[A2dpProfilePeer]%{public}s IsPeerSinkCodecValid() failed \n", __func__);
265 return false;
266 }
267 UpdatePeerCapabilityInfo(acpSeid, cap, role);
268 } else {
269 // check valid
270 if (!IsPeerSourceCodecValid(codecInfo)) {
271 LOG_ERROR("[A2dpProfilePeer]%{public}s IsPeerSourceCodecValid failed\n", __func__);
272 return false;
273 }
274 UpdatePeerCapabilityInfo(acpSeid, cap, role);
275 }
276 LOG_INFO("[A2dpProfilePeer]%{public}s SetSinkCodecConfig result(%{public}d)\n", __func__, ret);
277 return ret;
278 }
279
UpdatePeerCapabilityInfo(uint8_t acpSeid,AvdtSepConfig cap,uint8_t role)280 void A2dpProfilePeer::UpdatePeerCapabilityInfo(uint8_t acpSeid, AvdtSepConfig cap, uint8_t role)
281 {
282 uint8_t *codecInfo = cap.codecInfo;
283
284 if (role == A2DP_ROLE_SOURCE) {
285 for (int i = 0; i < sourceStreamNum_; i++) {
286 LOG_INFO("[A2dpProfilePeer]%{public}s Local codec index(%u), peercapIndex(%u)\n",
287 __func__,
288 streamCtrl_[i].GetCodecInfo().codecIndex,
289 GetSinkCodecIndex(codecInfo));
290 if (streamCtrl_[i].GetCodecInfo().codecIndex == A2DP_SOURCE_CODEC_INDEX_AAC) {
291 SetOptionalCodecsSupportState(A2DP_OPTIONAL_SUPPORT);
292 }
293 if ((streamCtrl_[i].GetCodecInfo().codecIndex + A2DP_SINK_CODEC_INDEX_MIN - 1) ==
294 GetSinkCodecIndex(codecInfo)) {
295 streamCtrl_[i].SetPeerCapability(cap);
296 streamCtrl_[i].SetAcpSeid(acpSeid);
297 selectbleStreamIndex_ = i;
298 if (!streamCtrl_[i].GetPeerCap()) {
299 SetNumberOfPeerCap(true);
300 streamCtrl_[i].SetPeerCap(true);
301 }
302 break;
303 }
304 }
305 } else {
306 for (int i = 0; i < sinkStreamNum_; i++) {
307 LOG_INFO("[A2dpProfilePeer]%{public}s Local(source) codec index(%u) peerCapIndex(%u)\n",
308 __func__,
309 streamCtrl_[i].GetCodecInfo().codecIndex,
310 GetSourceCodecIndex(codecInfo));
311 if (streamCtrl_[i].GetCodecInfo().codecIndex == A2DP_SINK_CODEC_INDEX_AAC) {
312 SetOptionalCodecsSupportState(A2DP_OPTIONAL_SUPPORT);
313 }
314
315 if ((streamCtrl_[i].GetCodecInfo().codecIndex + 1 - A2DP_SINK_CODEC_INDEX_MIN) ==
316 GetSourceCodecIndex(codecInfo)) {
317 streamCtrl_[i].SetPeerCapability(cap);
318 selectbleStreamIndex_ = i;
319 streamCtrl_[i].SetAcpSeid(acpSeid);
320 if (!streamCtrl_[i].GetPeerCap()) {
321 SetNumberOfPeerCap(true);
322 streamCtrl_[i].SetPeerCap(true);
323 }
324 break;
325 }
326 }
327 }
328 }
329
SetStreamHandle(uint16_t handle)330 void A2dpProfilePeer::SetStreamHandle(uint16_t handle)
331 {
332 LOG_INFO("[A2dpProfilePeer] %{public}s handle(%u)\n", __func__, handle);
333 streamHandle_ = handle;
334 }
335
SetAcpSeid(uint8_t seid)336 void A2dpProfilePeer::SetAcpSeid(uint8_t seid)
337 {
338 LOG_INFO("[A2dpProfilePeer] %{public}s seid(%u)\n", __func__, seid);
339 acpId_ = seid;
340 }
341
SetIntSeid(uint8_t seid)342 void A2dpProfilePeer::SetIntSeid(uint8_t seid)
343 {
344 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
345
346 LOG_INFO("[A2dpProfilePeer] %{public}s seid(%u)\n", __func__, seid);
347 intId_ = seid;
348 }
349
GetAcpSeid() const350 uint8_t A2dpProfilePeer::GetAcpSeid() const
351 {
352 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
353
354 LOG_INFO("[A2dpProfilePeer] %{public}s acpId_(%u)\n", __func__, acpId_);
355 return acpId_;
356 }
357
GetIntSeid() const358 uint8_t A2dpProfilePeer::GetIntSeid() const
359 {
360 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
361 LOG_INFO("[A2dpProfilePeer] %{public}s intId_(%u)\n", __func__, intId_);
362 return intId_;
363 }
364
GetPeerSepNum() const365 uint8_t A2dpProfilePeer::GetPeerSepNum() const
366 {
367 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
368 LOG_INFO("[A2dpProfilePeer] %{public}s peerNumSeps_(%u)\n", __func__, peerNumSeps_);
369 return peerNumSeps_;
370 }
371
GetStreamHandle() const372 uint16_t A2dpProfilePeer::GetStreamHandle() const
373 {
374 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
375 LOG_INFO("[A2dpProfilePeer] %{public}s streamHandle_(%u)\n", __func__, streamHandle_);
376 return streamHandle_;
377 }
378
GetPeerSEPInformation() const379 AvdtSepInfo A2dpProfilePeer::GetPeerSEPInformation() const
380 {
381 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
382 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
383
384 AvdtSepInfo sepDetail = {};
385 if (peerSepIndex_ < peerNumSeps_) {
386 sepDetail = peerSepInfo_[peerSepIndex_];
387 }
388 return sepDetail;
389 }
390
UpdateSepIndex()391 void A2dpProfilePeer::UpdateSepIndex()
392 {
393 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
394 LOG_INFO("[A2dpProfilePeer] %{public}s peerSepIndex_(%u)\n", __func__, peerSepIndex_);
395 peerSepIndex_++;
396 }
397
GetPeerAddress() const398 BtAddr A2dpProfilePeer::GetPeerAddress() const
399 {
400 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
401 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
402 return peerAddress_;
403 }
404
GetPeerCapabilityInfo() const405 AvdtSepConfig A2dpProfilePeer::GetPeerCapabilityInfo() const
406 {
407 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
408 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
409
410 return streamCtrl_[selectbleStreamIndex_].GetPeerSEPInformation();
411 }
412
GetStateMachine()413 A2dpStateMachine *A2dpProfilePeer::GetStateMachine()
414 {
415 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
416 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
417
418 return &stateMachine_;
419 }
420
SetSDPServiceCapability(bool value)421 void A2dpProfilePeer::SetSDPServiceCapability(bool value)
422 {
423 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
424 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
425
426 isService_ = value;
427 }
GetSDPServiceCapability() const428 bool A2dpProfilePeer::GetSDPServiceCapability() const
429 {
430 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
431 LOG_INFO("[A2dpProfilePeer]%{public}s isService(%{public}d)\n", __func__, isService_);
432
433 return isService_;
434 }
SetAvdtpVersion(bool value)435 void A2dpProfilePeer::SetAvdtpVersion(bool value)
436 {
437 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
438 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
439
440 avdtpVer132_ = value;
441 }
442
GetAvdtpVersion() const443 bool A2dpProfilePeer::GetAvdtpVersion() const
444 {
445 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
446 LOG_INFO("[A2dpProfilePeer]%{public}s avdtpVer132(%{public}d)\n", __func__, avdtpVer132_);
447
448 return avdtpVer132_;
449 }
SetA2dpVersion(bool value)450 void A2dpProfilePeer::SetA2dpVersion(bool value)
451 {
452 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
453 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
454
455 a2dpVer132_ = value;
456 }
457
GetA2dpVersion() const458 bool A2dpProfilePeer::GetA2dpVersion() const
459 {
460 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
461 LOG_INFO("[A2dpProfilePeer]%{public}s a2dpVer132(%{public}d)\n", __func__, a2dpVer132_);
462
463 return a2dpVer132_;
464 }
465
GetCodecConfigure() const466 A2dpCodecFactory *A2dpProfilePeer::GetCodecConfigure() const
467 {
468 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
469
470 return codecConfig_;
471 }
472
JudgeCapabilityMatched(uint8_t role)473 bool A2dpProfilePeer::JudgeCapabilityMatched(uint8_t role)
474 {
475 LOG_INFO("[A2dpProfilePeer]%{public}s role(%u)\n", __func__, role);
476 bool ret = false;
477
478 if (role == A2DP_ROLE_SOURCE) {
479 for (auto config : codecConfig_->GetIndexedSourceCodecs()) {
480 if (FindCapabilityMatched(*config, role)) {
481 return true;
482 }
483 }
484 } else {
485 for (auto config : codecConfig_->GetIndexedSinkCodecs()) {
486 if (FindCapabilityMatched(*config, role)) {
487 return true;
488 }
489 }
490 }
491
492 return ret;
493 }
494
FindCapabilityMatched(const A2dpCodecConfig & config,const uint8_t role)495 bool A2dpProfilePeer::FindCapabilityMatched(const A2dpCodecConfig &config, const uint8_t role)
496 {
497 LOG_INFO("[A2dpProfilePeer]%{public}s", __func__);
498 uint8_t resultConfig[A2DP_CODEC_SIZE] = {0};
499 uint8_t *resConigInfo = &resultConfig[0];
500 uint8_t cap[A2DP_CODEC_SIZE] = {0};
501 uint8_t *codecInfo = cap;
502 bool ret = false;
503 if (role == A2DP_ROLE_SOURCE) {
504 for (int i = 0; i < sourceStreamNum_; i++) {
505 LOG_INFO("[A2dpProfilePeer]%{public}s PriorityIndex(%u), streamIndex(%u)\n",
506 __func__, config.GetCodecIndex(),
507 streamCtrl_[i].GetCodecInfo().codecIndex);
508 if (config.GetCodecIndex() == streamCtrl_[i].GetCodecInfo().codecIndex &&
509 streamCtrl_[i].GetAcpSeid() != 0 && GetInitSide()) {
510 selectbleStreamIndex_ = i;
511 SetIntSeid(streamCtrl_[i].GetHandle());
512 SetAcpSeid(streamCtrl_[i].GetAcpSeid());
513 (void)memcpy_s(cap, A2DP_CODEC_SIZE,
514 streamCtrl_[i].GetPeerSEPInformation().codecInfo, A2DP_CODEC_SIZE);
515 ret = codecConfig_->SetCodecConfig(codecInfo, resConigInfo);
516 LOG_INFO("[A2dpProfilePeer]%{public}s ret(%{public}d)\n", __func__, ret);
517 return true;
518 } else if (config.GetCodecIndex() == streamCtrl_[i].GetCodecInfo().codecIndex &&
519 streamCtrl_[i].GetAcpSeid() != 0) {
520 selectbleStreamIndex_ = i;
521 SetIntSeid(streamCtrl_[i].GetHandle());
522 SetAcpSeid(streamCtrl_[i].GetAcpSeid());
523 return true;
524 } else {
525 LOG_INFO("[A2dpProfilePeer]%{public}s current capability is not matched. \n", __func__);
526 }
527 }
528 } else {
529 for (int i = 0; i < sinkStreamNum_; i++) {
530 if (config.GetCodecIndex() == streamCtrl_[i].GetCodecInfo().codecIndex &&
531 streamCtrl_[i].GetAcpSeid() != 0) {
532 selectbleStreamIndex_ = i;
533 SetIntSeid(streamCtrl_[i].GetHandle());
534 SetAcpSeid(streamCtrl_[i].GetAcpSeid());
535 (void)memcpy_s(cap, A2DP_CODEC_SIZE,
536 streamCtrl_[i].GetPeerSEPInformation().codecInfo, A2DP_CODEC_SIZE);
537 ret = codecConfig_->SetSinkCodecConfig(codecInfo, resConigInfo);
538 LOG_INFO("[A2dpProfilePeer]%{public}s ret(%{public}d) cap(%u)\n",
539 __func__, ret, cap[A2DP_CODEC_TYPE_INDEX]);
540 return true;
541 }
542 }
543 }
544 return ret;
545 }
546
SDPServiceCallback(const BtAddr * addr,const SdpService * serviceArray,const uint16_t serviceNum,void * context)547 void A2dpProfilePeer::SDPServiceCallback(
548 const BtAddr *addr, const SdpService *serviceArray, const uint16_t serviceNum, void *context)
549 {
550 uint8_t role = ((A2dpProfile *)context)->GetRole();
551 A2dpService *service = GetServiceInstance(role);
552 BtAddr address = *addr;
553 int result = static_cast<int>(A2DP_SUCCESS);
554
555 LOG_INFO("[A2dpProfilePeer] %{public}s role(%u) serviceNum(%u)\n", __func__, role, serviceNum);
556
557 if (service == nullptr) {
558 LOG_ERROR("[A2dpProfilePeer] %{public}s role(%u): Can't find the service\n", __func__, role);
559 return;
560 }
561 if (serviceNum == 0) {
562 result = A2DP_BADPARAM;
563 } else {
564 /// save the sdp search attributes
565 ParseSDPInformation(address, serviceArray, serviceNum, role);
566 }
567 utility::Message msgData(A2DP_SDP_EVT, result, context);
568 RawAddress peerAddr = RawAddress::ConvertToString(address.addr);
569
570 service->PostEvent(msgData, peerAddr);
571 }
572
ParseSDPInformation(const BtAddr & addr,const SdpService * serviceArray,uint16_t serviceNum,uint8_t role)573 void A2dpProfilePeer::ParseSDPInformation(
574 const BtAddr &addr, const SdpService *serviceArray, uint16_t serviceNum, uint8_t role)
575 {
576 LOG_INFO("[A2dpProfilePeer]%{public}s serviceNum(%u)\n", __func__, serviceNum);
577
578 A2dpProfile *instance = GetProfileInstance(role);
579 A2dpProfilePeer *profilePeer = instance->FindPeerByAddress(addr);
580 if (profilePeer == nullptr) {
581 LOG_ERROR("[A2dpProfilePeer]%{public}s Not find peer instance", __func__);
582 return;
583 }
584
585 for (int i = 0; i < serviceNum; i++) {
586 if ((role == A2DP_ROLE_SOURCE && (serviceArray[i].classId->uuid16 == A2DP_SINK_SERVICE_CLASS_UUID)) ||
587 (role == A2DP_ROLE_SINK && (serviceArray[i].classId->uuid16 == A2DP_SERVICE_CLASS_UUID))) {
588 profilePeer->SetSDPServiceCapability(true);
589 } else {
590 profilePeer->SetSDPServiceCapability(false);
591 }
592 if (serviceArray[i].descriptor[0].protocolUuid.uuid16 == A2DP_PROTOCOL_UUID_L2CAP &&
593 serviceArray[i].descriptor[0].parameter[0].value == A2DP_PROTOCOL_UUID_AVDTP &&
594 serviceArray[i].descriptor[1].protocolUuid.uuid16 == A2DP_PROTOCOL_UUID_AVDTP &&
595 serviceArray[i].descriptor[1].parameter[0].value == A2DP_PROFILE_REV_1_3) {
596 profilePeer->SetAvdtpVersion(true);
597 } else {
598 profilePeer->SetAvdtpVersion(false);
599 }
600 if (serviceArray[i].profileDescriptor[0].profileUuid.uuid16 == A2DP_PROFILE_UUID &&
601 serviceArray[i].profileDescriptor[0].versionNumber == A2DP_PROFILE_REV_1_3) {
602 profilePeer->SetA2dpVersion(true);
603 } else {
604 profilePeer->SetA2dpVersion(false);
605 }
606 }
607 }
608
SetSignalingTimer(int ms,bool isPeriodic) const609 void A2dpProfilePeer::SetSignalingTimer(int ms, bool isPeriodic) const
610 {
611 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
612
613 if (signalingTimer_ != nullptr) {
614 signalingTimer_->Start(ms, isPeriodic);
615 }
616 }
617
StopSignalingTimer() const618 void A2dpProfilePeer::StopSignalingTimer() const
619 {
620 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
621
622 if (signalingTimer_ != nullptr) {
623 signalingTimer_->Stop();
624 }
625 }
626
ProcessSignalingTimeoutCallback()627 void A2dpProfilePeer::ProcessSignalingTimeoutCallback()
628 {
629 LOG_INFO("[A2dpProfilePeer]%{public}s failed to cmd(%u)\n", __func__, GetCurrentCmd());
630
631 A2dpAvdtMsg msg = {};
632 utility::Message msgData((int)EVT_TIME_OUT, (int)0, &msg);
633
634 if (GetCurrentCmd() != EVT_DISCONNECT_REQ) {
635 msg.a2dpMsg.stream.addr = peerAddress_;
636 msg.role = localRole_;
637 msgData.arg2_ = &msg;
638 GetStateMachine()->ProcessMessage(msgData);
639 } else {
640 /// Do nothing
641 LOG_INFO("[A2dpProfilePeer]%{public}s Disconnect Req\n", __func__);
642 }
643 }
644
SetCurrentCmd(uint8_t cmd)645 void A2dpProfilePeer::SetCurrentCmd(uint8_t cmd)
646 {
647 LOG_INFO("[A2dpProfilePeer]%{public}s cmd(%u)\n", __func__, cmd);
648 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
649
650 currentCmd_ = cmd;
651 }
652
GetCurrentCmd() const653 uint8_t A2dpProfilePeer::GetCurrentCmd() const
654 {
655 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
656
657 LOG_INFO("[A2dpProfilePeer]%{public}s currentCmd(%u)\n", __func__, currentCmd_);
658 return currentCmd_;
659 }
660
SetUserCodecConfigure(const A2dpSrcCodecInfo & info)661 int A2dpProfilePeer::SetUserCodecConfigure(const A2dpSrcCodecInfo &info)
662 {
663 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
664 int ret;
665 A2dpCodecCapability userConfig = {};
666 uint8_t capability[A2DP_CODEC_SIZE] = {0};
667 uint8_t resultCapability[A2DP_CODEC_SIZE] = {0};
668 bool reconfig = false;
669 A2dpCodecType preCodecIndex = A2DP_CODEC_TYPE_SBC;
670 A2dpCodecType codecIndexChanged = A2DP_CODEC_TYPE_SBC;
671 uint8_t *codecInfo = capability;
672
673 if (codecConfig_->GetCodecConfig() == nullptr) {
674 return RET_BAD_PARAM;
675 }
676 if (codecConfig_->GetCodecConfig()->GetCodecIndex() != A2DP_SOURCE_CODEC_INDEX_SBC) {
677 preCodecIndex = A2DP_CODEC_TYPE_AAC;
678 }
679 ChangeUserConfigureInfo(userConfig, codecInfo, info);
680
681 uint8_t *resultInfo = resultCapability;
682 if (codecConfig_->SetCodecUserConfig(userConfig, codecInfo, resultInfo, &reconfig)) {
683 LOG_INFO("[A2dpProfilePeer]%{public}s reconfig(%{public}d) \n", __func__, reconfig);
684 if (info.codecType == A2DP_CODEC_TYPE_AAC) {
685 codecReconfig_.numCodec = A2DP_CODEC_AAC_INFO_LEN;
686 } else {
687 codecReconfig_.numCodec = A2DP_CODEC_SBC_INFO_LEN;
688 }
689 if (reconfig) {
690 bool closeStream = false;
691 (void)memcpy_s(codecReconfig_.codecInfo, A2DP_CODEC_SIZE, resultCapability, A2DP_CODEC_SIZE);
692 codecReconfig_.mediaType = A2DP_MEDIA_TYPE_AUDIO;
693 if (codecConfig_->FindSourceCodec(resultInfo) == nullptr) {
694 return RET_BAD_PARAM;
695 }
696 if (codecConfig_->FindSourceCodec(resultInfo)->GetCodecIndex() != A2DP_SOURCE_CODEC_INDEX_SBC) {
697 codecIndexChanged = A2DP_CODEC_TYPE_AAC;
698 }
699 closeStream = (codecIndexChanged == preCodecIndex) ? false : true;
700 if (closeStream) {
701 codecReconfig_.pscMask = (AVDT_PSC_MSK_TRANS | AVDT_PSC_MSK_DELAY_RPT | AVDT_PSC_MSK_CODEC);
702 } else {
703 codecReconfig_.pscMask = AVDT_PSC_MSK_CODEC;
704 }
705 Reconfigure(closeStream);
706 NotifyAudioConfigChanged();
707 }
708 ret = BT_SUCCESS;
709 } else {
710 LOG_ERROR("[A2dpProfilePeer]%{public}s Failed to setCodecUserConfig\n", __func__);
711 ret = RET_BAD_PARAM;
712 }
713 return ret;
714 }
715
ChangeUserConfigureInfo(A2dpCodecCapability & userConfig,uint8_t * codecInfo,const A2dpSrcCodecInfo info)716 void A2dpProfilePeer::ChangeUserConfigureInfo(
717 A2dpCodecCapability &userConfig, uint8_t *codecInfo, const A2dpSrcCodecInfo info)
718 {
719 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
720 A2dpCodecIndex sourceCodecIndex = A2DP_SOURCE_CODEC_INDEX_SBC;
721
722 if (A2DP_CODEC_TYPE_AAC == info.codecType) {
723 sourceCodecIndex = A2DP_SOURCE_CODEC_INDEX_AAC;
724 }
725 userConfig.bitsPerSample = info.bitsPerSample;
726 userConfig.channelMode_ = info.channelMode;
727 userConfig.codecIndex_ = sourceCodecIndex;
728 userConfig.codecPriority_ = A2DP_CODEC_PRIORITY_HIGHEST;
729 userConfig.sampleRate_ = info.sampleRate;
730
731 for (int i = 0; i < sourceStreamNum_; i++) {
732 if (sourceCodecIndex == streamCtrl_[i].GetCodecInfo().codecIndex) {
733 selectbleStreamIndex_ = i;
734 (void)memcpy_s(codecInfo, A2DP_CODEC_SIZE,
735 streamCtrl_[i].GetPeerSEPInformation().codecInfo, A2DP_CODEC_SIZE);
736 if (info.codecType == A2DP_CODEC_TYPE_SBC) {
737 *(codecInfo + CODEC_SBC_SAMPLE_INDEX) = (userConfig.sampleRate_ | userConfig.channelMode_);
738 LOG_INFO("[A2dpProfilePeer]%{public}s SBC Freq&chan(%u)\n",
739 __func__, *(codecInfo + CODEC_SBC_SAMPLE_INDEX));
740 } else {
741 *(codecInfo + CODEC_AAC_SAMPLE4) = userConfig.sampleRate_;
742 *(codecInfo + CODEC_AAC_SAMPLE5) =
743 ((userConfig.sampleRate_ >> CODEC_BIT_MOVE8) | userConfig.channelMode_);
744 *(codecInfo + CODEC_AAC_BIT6) = userConfig.bitsPerSample >> CODEC_BIT_MOVE16;
745 *(codecInfo + CODEC_AAC_BIT7) = userConfig.bitsPerSample >> CODEC_BIT_MOVE8;
746 *(codecInfo + CODEC_AAC_BIT8) = userConfig.bitsPerSample;
747 LOG_INFO("[A2dpProfilePeer]%{public}s AAC Freq(%u)\n", __func__, *(codecInfo + CODEC_AAC_SAMPLE4));
748 LOG_INFO("[A2dpProfilePeer]%{public}s AAC Freq&chan(%u)\n", __func__,
749 *(codecInfo + CODEC_AAC_SAMPLE5));
750 }
751 break;
752 }
753 }
754 }
755
EnableOptionalCodec(bool value)756 bool A2dpProfilePeer::EnableOptionalCodec(bool value)
757 {
758 LOG_INFO("[A2dpProfilePeer]%{public}s value(%{public}d)\n", __func__, value);
759 bool ret = true;
760 A2dpCodecCapability userConfig = {};
761 bool reconfig = false;
762 uint8_t capability[A2DP_CODEC_SIZE] = {0};
763 uint8_t resultCapability[A2DP_CODEC_SIZE] = {0};
764 uint8_t *capInfo = nullptr;
765 uint8_t *resultInfo = nullptr;
766 capInfo = capability;
767 resultInfo = resultCapability;
768
769 if (value) {
770 SelectCodecInfo(userConfig, capInfo, A2DP_SOURCE_CODEC_INDEX_AAC);
771 } else {
772 SelectCodecInfo(userConfig, capInfo, A2DP_SOURCE_CODEC_INDEX_SBC);
773 }
774 userConfig.codecPriority_ = A2DP_CODEC_PRIORITY_HIGHEST;
775 ret = codecConfig_->SetCodecUserConfig(userConfig, capInfo, resultInfo, &reconfig);
776 for (int i = 0; i < CODEC_INFO_LEN; i++) {
777 LOG_INFO("[A2dpProfilePeer]%{public}s capInfo(%u)\n", __func__, *(capInfo + i));
778 LOG_INFO("[A2dpProfilePeer]%{public}s resultInfo(%u)\n", __func__, *(resultInfo + i));
779 }
780
781 if (ret && reconfig) {
782 (void)memcpy_s(codecReconfig_.codecInfo, A2DP_CODEC_SIZE, resultCapability, A2DP_CODEC_SIZE);
783 codecReconfig_.mediaType = A2DP_MEDIA_TYPE_AUDIO;
784 if (value) {
785 codecReconfig_.numCodec = A2DP_CODEC_AAC_INFO_LEN;
786 } else {
787 codecReconfig_.numCodec = A2DP_CODEC_SBC_INFO_LEN;
788 }
789 codecReconfig_.pscMask = (AVDT_PSC_MSK_TRANS | AVDT_PSC_MSK_DELAY_RPT | AVDT_PSC_MSK_CODEC);
790 Reconfigure(true);
791 }
792 return ret;
793 }
794
SelectCodecInfo(A2dpCodecCapability & userConfig,uint8_t * codecInfo,A2dpCodecIndex index)795 void A2dpProfilePeer::SelectCodecInfo(A2dpCodecCapability &userConfig, uint8_t *codecInfo, A2dpCodecIndex index)
796 {
797 LOG_INFO("[A2dpProfilePeer]%{public}s \n", __func__);
798
799 userConfig.codecIndex_ = index;
800 for (int i = 0; i < sourceStreamNum_; i++) {
801 if (index == streamCtrl_[i].GetCodecInfo().codecIndex) {
802 selectbleStreamIndex_ = i;
803 (void)memcpy_s(codecInfo, A2DP_CODEC_SIZE,
804 streamCtrl_[i].GetPeerSEPInformation().codecInfo, A2DP_CODEC_SIZE);
805 if (index == A2DP_SOURCE_CODEC_INDEX_SBC) {
806 userConfig.bitsPerSample = *(codecInfo + CODEC_AAC_SAMPLE5);
807 userConfig.channelMode_ = *(codecInfo + CODEC_SBC_SAMPLE_INDEX) & 0x0F;
808 userConfig.sampleRate_ = *(codecInfo + CODEC_SBC_SAMPLE_INDEX) & 0xF0;
809 } else {
810 userConfig.bitsPerSample = *(codecInfo + CODEC_AAC_BIT6) & 0x7F;
811 userConfig.bitsPerSample =
812 (userConfig.bitsPerSample << CODEC_BIT_MOVE8) | *(codecInfo + CODEC_AAC_BIT7);
813 userConfig.bitsPerSample =
814 (userConfig.bitsPerSample << CODEC_BIT_MOVE8) | *(codecInfo + CODEC_AAC_BIT8);
815 userConfig.channelMode_ = *(codecInfo + CODEC_AAC_SAMPLE5) & 0x0C;
816 userConfig.sampleRate_ = *(codecInfo + CODEC_AAC_SAMPLE5) & 0xF0;
817 userConfig.sampleRate_ =
818 (userConfig.sampleRate_ << CODEC_BIT_MOVE8) | *(codecInfo + CODEC_AAC_SAMPLE4);
819 }
820 break;
821 }
822 }
823 }
824
NotifyEncoder()825 void A2dpProfilePeer::NotifyEncoder()
826 {
827 LOG_INFO("[A2dpProfilePeer]%{public}s \n", __func__);
828 A2dpCodecThread *codecThread = A2dpCodecThread::GetInstance();
829 utility::Message msg(A2DP_PCM_ENCODED, localRole_, nullptr);
830 A2dpEncoderInitPeerParams peerParams = {};
831 A2dpCodecConfig *config = nullptr;
832
833 if (codecThread != nullptr) {
834 IPowerManager::GetInstance().StatusUpdate(
835 RequestStatus::BUSY, PROFILE_NAME_A2DP_SRC, bluetooth::RawAddress::ConvertToString(peerAddress_.addr));
836 if (edr_) {
837 peerParams.isPeerEdr = true;
838 } else {
839 peerParams.isPeerEdr = false;
840 }
841 if (edr_ & A2DP_PEER_3MB) {
842 peerParams.peerSupports3mbps = true;
843 } else {
844 peerParams.peerSupports3mbps = false;
845 }
846 peerParams.peermtu = mtu_;
847 config = codecConfig_->GetCodecConfig();
848 LOG_INFO("[A2dpProfilePeer]%{public}s edr(%{public}d) 3Mb(%{public}d) \n", __func__, peerParams.isPeerEdr,
849 peerParams.peerSupports3mbps);
850 codecThread->ProcessMessage(msg, peerParams, config, nullptr);
851 } else {
852 LOG_ERROR("[A2dpProfilePeer]%{public}s Can't find the instance of codec \n", __func__);
853 }
854 }
855
NotifyDecoder()856 void A2dpProfilePeer::NotifyDecoder()
857 {
858 A2dpCodecThread *codecThread = A2dpCodecThread::GetInstance();
859 utility::Message msg(A2DP_FRAME_DECODED, localRole_, nullptr);
860 A2dpCodecConfig *config = nullptr;
861 A2dpEncoderInitPeerParams peerParams = {};
862
863 if (codecThread != nullptr) {
864 config = codecConfig_->GetCodecConfig();
865 if (decoderObserver_ == nullptr) {
866 decoderObserver_ = std::make_unique<A2dpCodecDecoderObserver>();
867 }
868 codecThread->ProcessMessage(msg, peerParams, config, decoderObserver_.get());
869 } else {
870 LOG_ERROR("[A2dpProfilePeer]%{public}s Can't find the instance of codec \n", __func__);
871 }
872 }
873
NotifyAudioConfigChanged() const874 void A2dpProfilePeer::NotifyAudioConfigChanged() const
875 {
876 LOG_INFO("[A2dpProfilePeer]%{public}s \n", __func__);
877 A2dpCodecThread *codecThread = A2dpCodecThread::GetInstance();
878 utility::Message msg(A2DP_AUDIO_RECONFIGURE, localRole_, nullptr);
879 A2dpEncoderInitPeerParams peerParams = {};
880
881 if (codecThread != nullptr) {
882 codecThread->ProcessMessage(msg, peerParams, nullptr, nullptr);
883 } else {
884 LOG_ERROR("[A2dpProfilePeer]%{public}s Can't find the instance of codec \n", __func__);
885 }
886 }
887
UpdateConfigure()888 void A2dpProfilePeer::UpdateConfigure()
889 {
890 LOG_INFO("[A2dpProfilePeer]%{public}s intId_(%u) acpId_(%u)\n", __func__, GetIntSeid(), GetAcpSeid());
891
892 A2dpAvdtMsg msgData = {};
893 msgData.a2dpMsg.configStream.addr = peerAddress_;
894 msgData.a2dpMsg.configStream.intSeid = GetIntSeid();
895 msgData.a2dpMsg.configStream.acpSeid = GetAcpSeid();
896 msgData.role = localRole_;
897 (void)memcpy_s(&msgData.a2dpMsg.configStream.cfg,
898 sizeof(ConfigureStream), &codecReconfig_, sizeof(ConfigureStream));
899 utility::Message msg(EVT_SETCONFIG_REQ, localRole_, &msgData);
900 restart_ = false;
901 stateMachine_.ProcessMessage(msg);
902 }
903
GetReconfig() const904 AvdtSepConfig A2dpProfilePeer::GetReconfig() const
905 {
906 LOG_INFO("[A2dpProfilePeer]%{public}s \n", __func__);
907 return codecReconfig_;
908 }
909
GetRestart() const910 bool A2dpProfilePeer::GetRestart() const
911 {
912 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
913 LOG_INFO("[A2dpProfilePeer]%{public}s restart_(%{public}d)\n", __func__, restart_);
914 return restart_;
915 }
916
SetRestart(bool value)917 void A2dpProfilePeer::SetRestart(bool value)
918 {
919 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
920 LOG_INFO("[A2dpProfilePeer]%{public}s value(%{public}d)\n", __func__, value);
921 restart_ = value;
922 }
923
GetReconfigTag() const924 bool A2dpProfilePeer::GetReconfigTag() const
925 {
926 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
927 LOG_INFO("[A2dpProfilePeer]%{public}s reconfigTag_(%{public}d)\n", __func__, reconfigTag_);
928 return reconfigTag_;
929 }
930
SetReconfigTag(bool value)931 void A2dpProfilePeer::SetReconfigTag(bool value)
932 {
933 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
934 LOG_INFO("[A2dpProfilePeer]%{public}s value(%{public}d)\n", __func__, value);
935 reconfigTag_ = value;
936 }
937
GetConfigure() const938 const ConfigureStream &A2dpProfilePeer::GetConfigure() const
939 {
940 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
941 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
942
943 return configureStream_;
944 }
945
SetConfigure()946 void A2dpProfilePeer::SetConfigure()
947 {
948 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
949
950 A2dpCodecConfig *curConfig = nullptr;
951 uint8_t codecInfo[A2DP_CODEC_SIZE];
952 uint8_t *curCodec = codecInfo;
953 (void)memset_s(codecInfo, A2DP_CODEC_SIZE, 0, A2DP_CODEC_SIZE);
954 (void)memset_s(&configureStream_, sizeof(ConfigureStream), 0, sizeof(ConfigureStream));
955
956 curConfig = codecConfig_->GetCodecConfig();
957 curConfig->CopyOutOtaCodecConfig(curCodec);
958 (void)memcpy_s(configureStream_.cfg.codecInfo, A2DP_CODEC_SIZE, codecInfo, A2DP_CODEC_SIZE);
959 configureStream_.cfg.mediaType = streamCtrl_[selectbleStreamIndex_].GetPeerSEPInformation().mediaType;
960 configureStream_.cfg.numCodec = streamCtrl_[selectbleStreamIndex_].GetPeerSEPInformation().numCodec;
961 configureStream_.cfg.pscMask = streamCtrl_[selectbleStreamIndex_].GetPeerSEPInformation().pscMask;
962 configureStream_.intSeid = intId_;
963 configureStream_.acpSeid = acpId_;
964 configureStream_.addr = peerAddress_;
965
966 LOG_INFO("[A2dpProfilePeer]%{public}s AcpSeid(%u) intseid(%u)\n",
967 __func__, configureStream_.acpSeid, configureStream_.intSeid);
968 }
969
SetNumberOfPeerCap(bool value)970 void A2dpProfilePeer::SetNumberOfPeerCap(bool value)
971 {
972 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
973
974 if (value) {
975 capNumber_++;
976 }
977 }
978
UpdatePeerMtu(uint16_t mtu)979 void A2dpProfilePeer::UpdatePeerMtu(uint16_t mtu)
980 {
981 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
982 LOG_INFO("[A2dpProfilePeer]%{public}s peer mtu size(%u) mtu_(%u)\n", __func__, mtu, mtu_);
983 if ((mtu >= 0) && (mtu < A2DP_MAX_AVDTP_MTU_SIZE)) {
984 mtu_ = mtu;
985 } else {
986 mtu_ = A2DP_MAX_AVDTP_MTU_SIZE;
987 }
988 }
989
UpdatePeerEdr(uint8_t edr)990 void A2dpProfilePeer::UpdatePeerEdr(uint8_t edr)
991 {
992 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
993 LOG_INFO("[A2dpProfilePeer]%{public}s peer edr(%u) edr_(%u)\n", __func__, edr, edr_);
994 edr_ = edr;
995 }
996
GetPeerCapComplete(uint8_t role) const997 bool A2dpProfilePeer::GetPeerCapComplete(uint8_t role) const
998 {
999 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
1000 LOG_INFO("[A2dpProfilePeer]%{public}s capNumber_(%u)\n", __func__, capNumber_);
1001
1002 if (role == A2DP_ROLE_SOURCE) {
1003 if (capNumber_ >= sourceStreamNum_) {
1004 return true;
1005 }
1006 } else {
1007 if (capNumber_ >= sinkStreamNum_) {
1008 return true;
1009 }
1010 }
1011 return false;
1012 }
1013
SetInitSide(bool value)1014 void A2dpProfilePeer::SetInitSide(bool value)
1015 {
1016 LOG_INFO("[A2dpProfilePeer]%{public}s (%{public}d)\n", __func__, value);
1017 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
1018
1019 isInitSide_ = value;
1020 }
1021
GetInitSide() const1022 bool A2dpProfilePeer::GetInitSide() const
1023 {
1024 LOG_INFO("[A2dpProfilePeer]%{public}s (%{public}d)\n", __func__, isInitSide_);
1025 std::lock_guard<std::recursive_mutex> lock(g_peerMutex);
1026
1027 return isInitSide_;
1028 }
1029
SetDisconnectIndication(bool value)1030 void A2dpProfilePeer::SetDisconnectIndication(bool value)
1031 {
1032 LOG_INFO("[A2dpProfilePeer]%{public}s (%{public}d)\n", __func__, value);
1033
1034 disconnectInd_ = value;
1035 }
1036
GetDisconnectIndication() const1037 bool A2dpProfilePeer::GetDisconnectIndication() const
1038 {
1039 LOG_INFO("[A2dpProfilePeer]%{public}s\n", __func__);
1040
1041 return disconnectInd_;
1042 }
1043
GetCodecStatus() const1044 A2dpSrcCodecStatus A2dpProfilePeer::GetCodecStatus() const
1045 {
1046 A2dpSrcCodecStatus codecStatus = {};
1047 A2dpSrcCodecInfo localCap = {};
1048 A2dpSrcCodecInfo selectableCap = {};
1049 auto config = codecConfig_->GetCodecConfig();
1050 if (config != nullptr) {
1051 uint8_t codecType = 0;
1052 LOG_INFO("[A2dpProfilePeer] %{public}s [codecIndex:%u]\n", __func__, config->GetCodecConfig().codecIndex_);
1053 if (A2DP_SOURCE_CODEC_INDEX_SBC == config->GetCodecConfig().codecIndex_ ||
1054 A2DP_SINK_CODEC_INDEX_SBC == config->GetCodecConfig().codecIndex_) {
1055 codecType = A2DP_CODEC_TYPE_SBC;
1056 } else {
1057 codecType = A2DP_CODEC_TYPE_AAC;
1058 }
1059 codecStatus.codecInfo.bitsPerSample = config->GetCodecConfig().bitsPerSample;
1060 codecStatus.codecInfo.channelMode = config->GetCodecConfig().channelMode_;
1061 codecStatus.codecInfo.codecPriority = config->GetCodecConfig().codecPriority_;
1062 codecStatus.codecInfo.sampleRate = config->GetCodecConfig().sampleRate_;
1063 codecStatus.codecInfo.codecType = codecType;
1064 LOG_INFO("[A2dpProfilePeer] %{public}s bitsPerSample(%u) \n", __func__, codecStatus.codecInfo.bitsPerSample);
1065 LOG_INFO("[A2dpProfilePeer] %{public}s channelMode(%u) \n", __func__, codecStatus.codecInfo.channelMode);
1066 LOG_INFO("[A2dpProfilePeer] %{public}s sampleRate(%u) \n", __func__, codecStatus.codecInfo.sampleRate);
1067 LOG_INFO("[A2dpProfilePeer] %{public}s codecType(%u) \n", __func__, codecStatus.codecInfo.codecType);
1068 LOG_INFO("[A2dpProfilePeer] %{public}s codecPriority(%u) \n", __func__, codecStatus.codecInfo.codecPriority);
1069 LOG_INFO("[A2dpProfilePeer] %{public}s get local cap info\n", __func__);
1070 localCap.bitsPerSample = config->GetCodecLocalCapability().bitsPerSample;
1071 localCap.channelMode = config->GetCodecLocalCapability().channelMode_;
1072 localCap.codecPriority = config->GetCodecLocalCapability().codecPriority_;
1073 localCap.sampleRate = config->GetCodecLocalCapability().sampleRate_;
1074 localCap.codecType = codecType;
1075 codecStatus.codecInfoLocalCap.push_back(localCap);
1076 LOG_INFO("[A2dpProfilePeer] %{public}s bitsPerSample(%u) \n", __func__, localCap.bitsPerSample);
1077 LOG_INFO("[A2dpProfilePeer] %{public}s channelMode(%u) \n", __func__, localCap.channelMode);
1078 LOG_INFO("[A2dpProfilePeer] %{public}s sampleRate(%u) \n", __func__, localCap.sampleRate);
1079 LOG_INFO("[A2dpProfilePeer] %{public}s codecType(%u) \n", __func__, localCap.codecType);
1080 LOG_INFO("[A2dpProfilePeer] %{public}s get peer cap info\n", __func__);
1081 for (int i = 0; i < sourceStreamNum_; i++) {
1082 FindPeerSelectableCapabilityMatched(selectableCap, streamCtrl_[i].GetPeerSEPInformation());
1083 codecStatus.codecInfoConfirmedCap.push_back(selectableCap);
1084 }
1085 }
1086
1087 return codecStatus;
1088 }
1089
FindPeerSelectableCapabilityMatched(A2dpSrcCodecInfo & selectableCap,AvdtSepConfig cap)1090 void A2dpProfilePeer::FindPeerSelectableCapabilityMatched(A2dpSrcCodecInfo &selectableCap, AvdtSepConfig cap)
1091 {
1092 uint8_t *codecInfo = cap.codecInfo;
1093
1094 for (int i = 0; i < CODEC_INFO_LEN; i++) {
1095 LOG_INFO("[A2dpProfilePeer]%{public}s codec[%u](0x:%x) \n", __func__, i, *(codecInfo + i));
1096 }
1097 if (*codecInfo++ == A2DP_CODEC_SBC_INFO_LEN) {
1098 selectableCap.codecType = A2DP_CODEC_TYPE_SBC;
1099 selectableCap.bitsPerSample = A2DP_SAMPLE_BITS_16;
1100 codecInfo++; // media type
1101 codecInfo++; // codec type
1102 selectableCap.sampleRate = *codecInfo & A2DP_SBC_SAMPLE_RATE_MSK;
1103 selectableCap.channelMode = *codecInfo & A2DP_SBC_CHANNEL_MODE_MSK;
1104 } else {
1105 uint32_t sampleRate = 0;
1106 selectableCap.codecType = A2DP_CODEC_TYPE_AAC;
1107 codecInfo++; // media type
1108 codecInfo++; // codec type
1109 codecInfo++; // object type
1110 sampleRate = (*codecInfo++ & A2DP_AAC_SAMPLE_RATE_OCTET1_MSK);
1111 LOG_INFO("[A2dpProfilePeer] %{public}s sampleRateLow(0x:%x) \n", __func__, sampleRate);
1112 selectableCap.sampleRate = ((*codecInfo) & A2DP_AAC_SAMPLE_RATE_OCTET2_MSK) << CODEC_BIT_MOVE8;
1113 LOG_INFO("[A2dpProfilePeer] %{public}s sampleRateHigh(0x:%x) \n", __func__, selectableCap.sampleRate);
1114 selectableCap.sampleRate = selectableCap.sampleRate | sampleRate;
1115 selectableCap.channelMode = *codecInfo++ & A2DP_AAC_CHANNEL_MODE_OCTET2_MSK;
1116 selectableCap.bitsPerSample = (*codecInfo++ & 0x7F) << CODEC_BIT_MOVE16;
1117 selectableCap.bitsPerSample = selectableCap.bitsPerSample | (*codecInfo++ << CODEC_BIT_MOVE8);
1118 selectableCap.bitsPerSample = selectableCap.bitsPerSample | *codecInfo;
1119 // need to adjust the bitpersample
1120 }
1121
1122 LOG_INFO("[A2dpProfilePeer] %{public}s bitsPerSample(0x:%x) \n", __func__, selectableCap.bitsPerSample);
1123 LOG_INFO("[A2dpProfilePeer] %{public}s channelMode(0x:%x) \n", __func__, selectableCap.channelMode);
1124 LOG_INFO("[A2dpProfilePeer] %{public}s sampleRate(0x:%x) \n", __func__, selectableCap.sampleRate);
1125 LOG_INFO("[A2dpProfilePeer] %{public}s codecType(0x:%x) \n", __func__, selectableCap.codecType);
1126 }
1127
Reconfigure(bool close)1128 void A2dpProfilePeer::Reconfigure(bool close)
1129 {
1130 LOG_INFO("[A2dpProfilePeer]%{public}s intId_(%u)\n", __func__, GetIntSeid());
1131 A2dpAvdtMsg msgData = {};
1132 msgData.role = localRole_;
1133 const uint8_t *codecInfo = codecReconfig_.codecInfo;
1134 A2dpStateMachine *stateMachine = GetStateMachine();
1135 SetRestart(true);
1136 if (close) {
1137 msgData.a2dpMsg.stream.handle = GetIntSeid();
1138 utility::Message msg(EVT_CLOSE_REQ, localRole_, &msgData);
1139 stateMachine->ProcessMessage(msg);
1140 SetCurrentCmd(EVT_CLOSE_REQ);
1141 SetSignalingTimer(A2DP_ACCEPT_SIGNALLING_TIMEOUT_MS, false);
1142 for (int i = 0; i < AVDT_NUM_SEPS; i++) {
1143 if (codecConfig_->FindSourceCodec(codecInfo) == nullptr) {
1144 continue;
1145 }
1146 if (codecConfig_->FindSourceCodec(codecInfo)->GetCodecIndex() ==
1147 streamCtrl_[i].GetCodecInfo().codecIndex) {
1148 SetIntSeid(streamCtrl_[i].GetHandle());
1149 SetAcpSeid(streamCtrl_[i].GetAcpSeid());
1150 LOG_INFO("[A2dpProfilePeer]%{public}s intId_(%u)\n", __func__, GetIntSeid());
1151 break;
1152 }
1153 if (i >= (AVDT_NUM_SEPS - 1)) {
1154 LOG_ERROR("[A2dpProfilePeer]%{public}s Can't fine stream index(%{public}d) \n", __func__, i);
1155 }
1156 }
1157 } else {
1158 if (strcmp(stateMachine->GetStateName().c_str(), A2DP_PROFILE_OPEN.c_str()) == 0) {
1159 msgData.a2dpMsg.configStream.intSeid = GetIntSeid();
1160 msgData.a2dpMsg.configStream.cfg = codecReconfig_;
1161 utility::Message msg(EVT_RECONFIG_REQ, localRole_, &msgData);
1162 SetRestart(false);
1163 stateMachine->ProcessMessage(msg);
1164 SetCurrentCmd(EVT_RECONFIG_REQ);
1165 SetSignalingTimer(A2DP_ACCEPT_SIGNALLING_TIMEOUT_MS, false);
1166 } else if (strcmp(stateMachine->GetStateName().c_str(), A2DP_PROFILE_STREAMING.c_str()) == 0) {
1167 msgData.a2dpMsg.stream.handle = GetIntSeid();
1168 utility::Message msg(EVT_SUSPEND_REQ, localRole_, &msgData);
1169 stateMachine->ProcessMessage(msg);
1170 SetCurrentCmd(EVT_SUSPEND_REQ);
1171 SetSignalingTimer(A2DP_ACCEPT_SIGNALLING_TIMEOUT_MS, false);
1172 } else {
1173 LOG_WARN("[A2dpProfilePeer]%{public}s The state(%{public}s) is no correct\n",
1174 __func__, stateMachine->GetStateName().c_str());
1175 }
1176 }
1177 }
1178
SignalingTimeoutCallback(uint8_t role) const1179 void A2dpProfilePeer::SignalingTimeoutCallback(uint8_t role) const
1180 {
1181 LOG_INFO("[A2dpProfilePeer]%{public}s \n", __func__);
1182 A2dpService *service = GetServiceInstance(role);
1183 if (service != nullptr) {
1184 utility::Message msgData(A2DP_TIMEOUT_EVT, role, nullptr);
1185 RawAddress peerAddr = RawAddress::ConvertToString(peerAddress_.addr);
1186 service->PostEvent(msgData, peerAddr);
1187 }
1188 }
1189
SetOptionalCodecsSupportState(int state) const1190 void A2dpProfilePeer::SetOptionalCodecsSupportState(int state) const
1191 {
1192 LOG_INFO("[A2dpService] %{public}s state(%{public}d)\n", __func__, state);
1193
1194 IProfileConfig *config = ProfileConfig::GetInstance();
1195 if (state == (int)A2DP_OPTIONAL_SUPPORT_UNKNOWN) {
1196 config->RemoveProperty(RawAddress::ConvertToString(peerAddress_.addr).GetAddress().c_str(),
1197 SECTION_CODE_CS_SUPPORT,
1198 PROPERTY_A2DP_SUPPORTS_OPTIONAL_CODECS);
1199 } else {
1200 config->SetValue(RawAddress::ConvertToString(peerAddress_.addr).GetAddress().c_str(),
1201 SECTION_CODE_CS_SUPPORT,
1202 PROPERTY_A2DP_SUPPORTS_OPTIONAL_CODECS,
1203 state);
1204 }
1205 }
1206
CreateDefaultCodecPriority()1207 void A2dpProfilePeer::CreateDefaultCodecPriority()
1208 {
1209 LOG_INFO("[A2dpProfilePeer]%{public}s \n", __func__);
1210 int value = 0;
1211 bool result = false;
1212 result = AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SRC_SERVICE, PROPERTY_CODEC_SBC, value);
1213 LOG_INFO("[A2dpProfilePeer]%{public}s SourceSBC Config(%{public}d) priority(%{public}d) \n",
1214 __func__, result, value);
1215 if (result) {
1216 defaultCodecPriorities_.insert(
1217 std::make_pair(A2DP_SOURCE_CODEC_INDEX_SBC, A2dpCodecPriority(value * PRIORITY_DEFAULT + 1)));
1218 } else {
1219 defaultCodecPriorities_.insert(
1220 std::make_pair(A2DP_SOURCE_CODEC_INDEX_SBC, A2dpCodecPriority(PRIORITY_DEFAULT + 1)));
1221 }
1222
1223 result = AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SRC_SERVICE, PROPERTY_CODEC_AAC, value);
1224 LOG_INFO("[A2dpProfilePeer]%{public}s SourceAAC Config(%{public}d) priority(%{public}d) \n",
1225 __func__, result, value);
1226 if (result) {
1227 if (localRole_ == A2DP_ROLE_SOURCE) {
1228 codecAACConfig = true;
1229 }
1230 defaultCodecPriorities_.insert(
1231 std::make_pair(A2DP_SOURCE_CODEC_INDEX_AAC, A2dpCodecPriority(value * PRIORITY_DEFAULT + 1)));
1232 }
1233
1234 // get sink codec configure
1235 result = AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SNK_SERVICE, PROPERTY_CODEC_SBC, value);
1236 LOG_INFO("[A2dpProfilePeer]%{public}s SinkSBC Config(%{public}d) priority(%{public}d) \n",
1237 __func__, result, value);
1238 if (result) {
1239 defaultCodecPriorities_.insert(
1240 std::make_pair(A2DP_SINK_CODEC_INDEX_SBC, A2dpCodecPriority(value * PRIORITY_DEFAULT + 1)));
1241 } else {
1242 defaultCodecPriorities_.insert(
1243 std::make_pair(A2DP_SINK_CODEC_INDEX_SBC,
1244 A2dpCodecPriority(PRIORITY_DEFAULT * A2DP_SINK_CODEC_INDEX_SBC + 1)));
1245 }
1246
1247 result = AdapterConfig::GetInstance()->GetValue(SECTION_A2DP_SNK_SERVICE, PROPERTY_CODEC_AAC, value);
1248 LOG_INFO("[A2dpProfilePeer]%{public}s Sink AAC Config(%{public}d) priority(%{public}d) \n",
1249 __func__, result, value);
1250 if (result) {
1251 if (localRole_ == A2DP_ROLE_SINK) {
1252 codecAACConfig = true;
1253 }
1254 defaultCodecPriorities_.insert(
1255 std::make_pair(A2DP_SINK_CODEC_INDEX_AAC, A2dpCodecPriority(value * PRIORITY_DEFAULT + 1)));
1256 }
1257 }
1258
SendPacket(const Packet * packet,size_t frames,uint32_t bytes,uint32_t pktTimeStamp) const1259 bool A2dpProfilePeer::SendPacket(const Packet *packet, size_t frames, uint32_t bytes,
1260 uint32_t pktTimeStamp) const
1261 {
1262 LOG_INFO("[A2dpProfilePeer] %{public}s \n", __func__);
1263
1264 bool ret = false;
1265 uint8_t payloadType = 0x0e;
1266 uint8_t marker = 0;
1267 A2dpAvdtp avdtp(A2DP_ROLE_SOURCE);
1268
1269 if (avdtp.WriteStream(streamHandle_, const_cast<Packet *>(packet), pktTimeStamp, payloadType, marker) ==
1270 A2DP_SUCCESS) {
1271 ret = true;
1272 }
1273
1274 return ret;
1275 }
1276 } // namespace bluetooth
1277 } // namespace OHOS
1278