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