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