1 /*
2 * Copyright (C) 2021 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_service_connection.h"
17
18 #include "a2dp_service.h"
19 #include "log.h"
20 #include "log_util.h"
21
22 namespace bluetooth {
A2dpConnectManager(uint8_t role)23 A2dpConnectManager::A2dpConnectManager(uint8_t role)
24 {
25 role_ = role;
26 }
27
A2dpConnect(const RawAddress & device)28 bool A2dpConnectManager::A2dpConnect(const RawAddress &device)
29 {
30 LOG_INFO("[A2dpConnectManager] %{public}s [address:%{public}s] role[%u]\n", __func__, GetEncryptAddr(device.GetAddress()).c_str(), role_);
31
32 A2dpService *service = GetServiceInstance(role_);
33 A2dpDeviceInfo *info = nullptr;
34
35 if (service == nullptr) {
36 LOG_ERROR("[A2dpConnectManager] %{public}s Can't get the instance of service\n", __func__);
37 return false;
38 }
39
40 for (auto bdr : service->GetDeviceList()) {
41 if (bdr.first == device.GetAddress().c_str()) {
42 info = bdr.second;
43 break;
44 }
45 }
46
47 if (info == nullptr) {
48 info = AddDevice(device, static_cast<int>(BTConnectState::DISCONNECTED));
49 }
50
51 if (info == nullptr) {
52 LOG_ERROR("[A2dpConnectManager] %{public}s role[%u] Can't add new device\n", __func__, role_);
53 return false;
54 }
55 RawAddress deviceObj = device;
56 utility::Message msg(A2DP_MSG_CONNECT, role_, &deviceObj);
57
58 info->SetConnectState(static_cast<int>(BTConnectState::CONNECTING));
59 info->GetStateMachine()->ProcessMessage(msg);
60
61 return true;
62 }
63
A2dpDisconnect(const RawAddress & device)64 bool A2dpConnectManager::A2dpDisconnect(const RawAddress &device)
65 {
66 LOG_INFO("[A2dpConnectManager] %{public}s\n", __func__);
67
68 A2dpService *service = GetServiceInstance(role_);
69
70 if (service == nullptr) {
71 LOG_ERROR("[A2dpConnectManager] %{public}s Can't get the instance of service\n", __func__);
72 return false;
73 }
74
75 A2dpDeviceInfo *deviceInfo = service->GetDeviceFromList(device);
76 if (deviceInfo == nullptr) {
77 LOG_ERROR("[A2dpConnectManager] %{public}s role[%u] Not find the device\n", __func__, role_);
78 return false;
79 }
80 // send message to statemachine
81 utility::Message msg(A2DP_MSG_DISCONNECT, role_, &const_cast<RawAddress &>(device));
82
83 deviceInfo->SetConnectState(static_cast<int>(BTConnectState::DISCONNECTING));
84 deviceInfo->GetStateMachine()->ProcessMessage(msg);
85
86 return true;
87 }
88
JudgeConnectedNum() const89 bool A2dpConnectManager::JudgeConnectedNum() const
90 {
91 LOG_INFO("[A2dpConnectManager] %{public}s\n", __func__);
92
93 A2dpService *service = GetServiceInstance(role_);
94
95 if (service == nullptr) {
96 LOG_ERROR("[A2dpConnectManager] %{public}s Can't get the instance of service\n", __func__);
97 return false;
98 }
99
100 bool ret = false;
101 int connectCnt = 0;
102
103 if (service->GetDeviceList().empty()) {
104 ret = true;
105 return ret;
106 } else {
107 for (auto itr : service->GetDeviceList()) {
108 LOG_INFO("[connectCnt] %u\n", connectCnt);
109 int connectionState = 0;
110 connectionState = itr.second->GetConnectState();
111 if (connectionState == static_cast<int>(BTConnectState::CONNECTED)) {
112 connectCnt++;
113 }
114 }
115 }
116
117 LOG_INFO("[connectCnt] %u\n", connectCnt);
118 ret = ((connectCnt >= service->GetMaxConnectNum()) ? false : true);
119 return ret;
120 }
121
AddDevice(const RawAddress & device,int state)122 A2dpDeviceInfo *A2dpConnectManager::AddDevice(const RawAddress &device, int state)
123 {
124 LOG_INFO("[A2dpConnectManager] %{public}s role[%u]\n", __func__, role_);
125
126 A2dpDeviceInfo *deviceInfo = nullptr;
127
128 A2dpService *service = GetServiceInstance(role_);
129 if (service == nullptr) {
130 LOG_INFO("[A2dpConnectManager] %{public}s Can't get the instance of service\n", __func__);
131 return deviceInfo;
132 }
133
134 auto peerDevice = std::make_unique<A2dpDeviceInfo>(device);
135 deviceInfo = peerDevice.release();
136 if (deviceInfo != nullptr) {
137 deviceInfo->GetStateMachine()->SetRole(role_);
138 deviceInfo->SetConnectState(state);
139 service->AddDeviceToList(device.GetAddress().c_str(), deviceInfo);
140 }
141
142 return deviceInfo;
143 }
144
JudgeConnectExit(const RawAddress & device,uint8_t role)145 bool A2dpConnectManager::JudgeConnectExit(const RawAddress &device, uint8_t role)
146 {
147 LOG_INFO("[A2dpConnectManager] %{public}s\n", __func__);
148
149 A2dpService *service = nullptr;
150 A2dpDeviceInfo *info = nullptr;
151 bool ret = false;
152
153 if (role == A2DP_ROLE_SINK) {
154 service = GetServiceInstance(A2DP_ROLE_SOURCE);
155 } else {
156 service = GetServiceInstance(A2DP_ROLE_SINK);
157 }
158
159 if (service != nullptr) {
160 std::map<std::string, A2dpDeviceInfo *> devList = service->GetDeviceList();
161 auto iter = devList.find(device.GetAddress().c_str());
162 if (iter == devList.end()) {
163 LOG_INFO("[A2dpService]Can't find the statemachine");
164 } else {
165 info = iter->second;
166 if ((static_cast<int>(BTConnectState::CONNECTED) == info->GetConnectState()) ||
167 (static_cast<int>(BTConnectState::CONNECTING) == info->GetConnectState())) {
168 LOG_ERROR("[A2dpService]Device have been connected as source role");
169 ret = true;
170 }
171 }
172 }
173 return ret;
174 }
175 } // namespace bluetooth