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 "power_manager.h"
17 #include <cstring>
18 #include <list>
19 #include <map>
20 #include <mutex>
21 #include <string>
22 #include "adapter_manager.h"
23 #include "btm.h"
24 #include "log.h"
25 #include "log_util.h"
26 #include "power_device.h"
27 #include "timer.h"
28
29 namespace bluetooth {
30 // static function
31 static std::unique_ptr<PowerManager> g_powerManager = nullptr;
GetInstance()32 IPowerManager &IPowerManager::GetInstance()
33 {
34 return PowerManager::GetInstance();
35 }
Initialize(utility::Dispatcher & dispatcher)36 void IPowerManager::Initialize(utility::Dispatcher &dispatcher)
37 {
38 g_powerManager->Initialize(dispatcher);
39 }
40
Uninitialize()41 void IPowerManager::Uninitialize()
42 {
43 g_powerManager->Uninitialize();
44 }
45
GetInstance()46 PowerManager &PowerManager::GetInstance()
47 {
48 return *(g_powerManager.get());
49 }
50
Initialize(utility::Dispatcher & dispatcher)51 void PowerManager::Initialize(utility::Dispatcher &dispatcher)
52 {
53 LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
54 if (g_powerManager == nullptr) {
55 g_powerManager = std::make_unique<PowerManager>(dispatcher);
56 }
57 }
58
Uninitialize()59 void PowerManager::Uninitialize()
60 {
61 LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
62 g_powerManager = nullptr;
63 }
64
65 /// PowerManager class
66 struct PowerManager::impl {
67 public:
implbluetooth::PowerManager::impl68 explicit impl(utility::Dispatcher &dispatcher) : dispatcher_(dispatcher)
69 {
70 LOG_DEBUG("PM_: impl %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
71 };
~implbluetooth::PowerManager::impl72 ~impl(){};
73
74 std::mutex mutex_ {};
75 std::atomic_bool isEnabled_ = false;
76 BtmPmCallbacks btmPmCallbacks_ {};
77 BtmAclCallbacks btmAclCallbacks_ {};
78 utility::Dispatcher &dispatcher_;
79 std::map<RawAddress, std::shared_ptr<PowerDevice>> powerDevices_ {};
80 std::map<uint16_t, RawAddress> connectionHandles_ {};
81
82 void PowerProcess(const RequestStatus status, const std::string &profileName, const RawAddress rawAddr);
83 void UpdatePowerDevicesInfo(const RawAddress rawAddr, const std::string &profileName, const RequestStatus status);
84
85 void ModeChangeCallBackProcess(uint8_t status, const RawAddress rawAddr, uint8_t currentMode, uint16_t interval);
86 static void ModeChangeCallBack(
87 uint8_t status, const BtAddr *btAddr, uint8_t currentMode, uint16_t interval, void *context);
88
89 void SsrCompleteCallBackProcess(uint8_t status, const RawAddress rawAddr);
90 static void SsrCompleteCallBack(uint8_t status, const BtAddr *btAddr, void *context);
91
92 void ConnectionCompleteCallBackProcess(const RawAddress rawAddr, uint16_t connectionHandle);
93 static void ConnectionCompleteCallBack(const BtmAclConnectCompleteParam *param, void *context);
94
95 void DisconnectionCompleteCallBackProcess(uint8_t status, uint16_t connectionHandle, uint8_t reason);
96 static void DisconnectionCompleteCallBack(uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context);
97
98 DISALLOW_COPY_AND_ASSIGN(impl);
99 };
100
PowerManager(utility::Dispatcher & dispatcher)101 PowerManager::PowerManager(utility::Dispatcher &dispatcher) : pimpl(std::make_unique<PowerManager::impl>(dispatcher))
102 {}
~PowerManager()103 PowerManager::~PowerManager()
104 {}
105
Enable()106 void PowerManager::Enable()
107 {
108 LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
109 pimpl->isEnabled_ = true;
110 int retVal = BTM_SetDefaultLinkPolicySettings(BTM_LINK_POLICY_ENABLE_ROLE_SWITCH |
111 BTM_LINK_POLICY_ENABLE_SNIFF_MODE);
112 LOG_DEBUG("PM_: BTM_SetDefaultLinkPolicySettings retVal: %{public}d\n", retVal);
113
114 pimpl->btmPmCallbacks_.modeChange = PowerManager::impl::ModeChangeCallBack;
115 pimpl->btmPmCallbacks_.setSniffSubratingComplete = PowerManager::impl::SsrCompleteCallBack;
116 pimpl->btmAclCallbacks_.connectionComplete = PowerManager::impl::ConnectionCompleteCallBack;
117 pimpl->btmAclCallbacks_.disconnectionComplete = PowerManager::impl::DisconnectionCompleteCallBack;
118
119 retVal = BTM_RegisterPmCallbacks(&pimpl->btmPmCallbacks_, this);
120 LOG_DEBUG("PM_: BTM_RegisterPmCallbacks retVal: %{public}d\n", retVal);
121
122 retVal = BTM_RegisterAclCallbacks(&pimpl->btmAclCallbacks_, this);
123 LOG_DEBUG("PM_: BTM_RegisterPmCallbacks retVal: %{public}d\n", retVal);
124 }
125
Disable()126 void PowerManager::Disable()
127 {
128 LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
129 pimpl->isEnabled_ = false;
130 BTM_DeregisterPmCallbacks(&pimpl->btmPmCallbacks_);
131 BTM_DeregisterAclCallbacks(&pimpl->btmAclCallbacks_);
132 pimpl->powerDevices_.clear();
133 }
134
StatusUpdate(const RequestStatus status,const std::string & profileName,const RawAddress & addr) const135 void PowerManager::StatusUpdate(
136 const RequestStatus status, const std::string &profileName, const RawAddress &addr) const
137 {
138 LOG_DEBUG("PM_: %{public}s, profileName: %{public}s, status: %u, addr: %{public}s\n",
139 __FUNCTION__,
140 profileName.c_str(),
141 status,
142 GetEncryptAddr(addr.GetAddress()).c_str());
143
144 if (pimpl->isEnabled_) {
145 pimpl->dispatcher_.PostTask(
146 std::bind(&PowerManager::impl::PowerProcess, pimpl.get(), status, profileName, addr));
147 }
148 }
149
GetPowerMode(const RawAddress & addr) const150 BTPowerMode PowerManager::GetPowerMode(const RawAddress &addr) const
151 {
152 std::unique_lock<std::mutex> lock(pimpl->mutex_);
153 auto iter = pimpl->powerDevices_.find(addr);
154 if (iter != pimpl->powerDevices_.end()) {
155 return iter->second->GetPowerMode();
156 }
157 return BTPowerMode::MODE_INVALID;
158 }
159
PowerProcess(const RequestStatus status,const std::string & profileName,const RawAddress rawAddr)160 void PowerManager::impl::PowerProcess(
161 const RequestStatus status, const std::string &profileName, const RawAddress rawAddr)
162 {
163 LOG_DEBUG(
164 "PM_: %{public}s start, status: %u, profileName: %{public}s, line: %{public}d\n", __FUNCTION__, status, profileName.c_str(), __LINE__);
165 std::unique_lock<std::mutex> lock(mutex_);
166 UpdatePowerDevicesInfo(rawAddr, profileName, status);
167 auto iter = powerDevices_.find(rawAddr);
168 if (iter != powerDevices_.end()) {
169 iter->second->SetPowerMode();
170 }
171 }
172
UpdatePowerDevicesInfo(const RawAddress rawAddr,const std::string & profileName,const RequestStatus status)173 void PowerManager::impl::UpdatePowerDevicesInfo(
174 const RawAddress rawAddr, const std::string &profileName, const RequestStatus status)
175 {
176 auto iter = powerDevices_.find(rawAddr);
177 if (iter == powerDevices_.end()) {
178 LOG_DEBUG("PM_: UpdatePowerDevicesInfo(), create powerDevices\n");
179 powerDevices_[rawAddr] = std::make_shared<PowerDevice>(rawAddr, dispatcher_);
180 }
181
182 if (status == RequestStatus::CONNECT_OFF) {
183 auto its = powerDevices_.find(rawAddr);
184 if (its != powerDevices_.end()) {
185 its->second->DeleteRequestPower(profileName);
186 }
187 } else {
188 LOG_DEBUG("PM_:: UpdatePowerDevicesInfo(), execute SetRequesetPower()\n");
189 powerDevices_[rawAddr]->SetRequestPower(profileName, status);
190 }
191 }
192
ModeChangeCallBackProcess(uint8_t status,const RawAddress rawAddr,uint8_t currentMode,uint16_t interval)193 void PowerManager::impl::ModeChangeCallBackProcess(
194 uint8_t status, const RawAddress rawAddr, uint8_t currentMode, uint16_t interval)
195 {
196 LOG_DEBUG("PM_: %{public}s start, status: %u, currentMode: %u, interval: %u, line: %{public}d\n",
197 __FUNCTION__,
198 status,
199 currentMode,
200 interval,
201 __LINE__);
202 std::unique_lock<std::mutex> lock(mutex_);
203 auto iter = powerDevices_.find(rawAddr);
204 if (iter == powerDevices_.end()) {
205 if (status != 0) {
206 LOG_DEBUG("PM_: ModeChangeCallBackProcess(), no need to create powerDevices for error status\n");
207 return;
208 }
209 LOG_DEBUG("PM_: ModeChangeCallBackProcess(), create powerDevices\n");
210 powerDevices_[rawAddr] = std::make_shared<PowerDevice>(rawAddr, dispatcher_);
211 }
212 powerDevices_[rawAddr]->ModeChangeCallBack(status, currentMode, interval);
213 }
214
ModeChangeCallBack(uint8_t status,const BtAddr * btAddr,uint8_t currentMode,uint16_t interval,void * context)215 void PowerManager::impl::ModeChangeCallBack(
216 uint8_t status, const BtAddr *btAddr, uint8_t currentMode, uint16_t interval, void *context)
217 {
218 RawAddress rawAddr = bluetooth::RawAddress::ConvertToString(btAddr->addr);
219 static_cast<PowerManager*>(context)
220 ->pimpl->dispatcher_.PostTask(std::bind(&PowerManager::impl::ModeChangeCallBackProcess,
221 static_cast<PowerManager*>(context)->pimpl.get(),
222 status,
223 rawAddr,
224 currentMode,
225 interval));
226 }
227
SsrCompleteCallBackProcess(uint8_t status,const RawAddress rawAddr)228 void PowerManager::impl::SsrCompleteCallBackProcess(uint8_t status, const RawAddress rawAddr)
229 {
230 LOG_DEBUG("PM_: %{public}s start, status: %u, line: %{public}d\n", __FUNCTION__, status, __LINE__);
231 std::unique_lock<std::mutex> lock(mutex_);
232 auto iter = powerDevices_.find(rawAddr);
233 if (iter != powerDevices_.end()) {
234 iter->second->SniffSubratingCompleteCallback(status);
235 }
236 }
237
SsrCompleteCallBack(uint8_t status,const BtAddr * btAddr,void * context)238 void PowerManager::impl::SsrCompleteCallBack(uint8_t status, const BtAddr *btAddr, void *context)
239 {
240 RawAddress rawAddr = bluetooth::RawAddress::ConvertToString(btAddr->addr);
241 static_cast<PowerManager*>(context)
242 ->pimpl->dispatcher_.PostTask(std::bind(
243 &PowerManager::impl::SsrCompleteCallBackProcess, static_cast<PowerManager*>(context)->pimpl.get(), status, rawAddr));
244 }
245
ConnectionCompleteCallBackProcess(const RawAddress rawAddr,uint16_t connectionHandle)246 void PowerManager::impl::ConnectionCompleteCallBackProcess(const RawAddress rawAddr, uint16_t connectionHandle)
247 {
248 LOG_DEBUG("PM_: ConnectionCompleteCallBackProcess(), addr=%{public}s\n",
249 GetEncryptAddr(rawAddr.GetAddress()).c_str());
250 // construct
251 std::unique_lock<std::mutex> lock(mutex_);
252 auto iter = powerDevices_.find(rawAddr);
253 if (iter == powerDevices_.end()) {
254 LOG_DEBUG("PM_: ConnectionCompleteCallBackProcess(), create powerDevices\n");
255 powerDevices_[rawAddr] = std::make_shared<PowerDevice>(rawAddr, dispatcher_);
256 }
257 connectionHandles_[connectionHandle] = rawAddr;
258 }
259
ConnectionCompleteCallBack(const BtmAclConnectCompleteParam * param,void * context)260 void PowerManager::impl::ConnectionCompleteCallBack(const BtmAclConnectCompleteParam *param, void *context)
261 {
262 RawAddress rawAddr = bluetooth::RawAddress::ConvertToString(param->addr->addr);
263 uint16_t connectionHandle = param->connectionHandle;
264 static_cast<PowerManager*>(context)
265 ->pimpl->dispatcher_.PostTask(std::bind(&PowerManager::impl::ConnectionCompleteCallBackProcess,
266 static_cast<PowerManager*>(context)->pimpl.get(),
267 rawAddr,
268 connectionHandle));
269 }
270
DisconnectionCompleteCallBackProcess(uint8_t status,uint16_t connectionHandle,uint8_t reason)271 void PowerManager::impl::DisconnectionCompleteCallBackProcess(uint8_t status, uint16_t connectionHandle, uint8_t reason)
272 {
273 LOG_DEBUG("PM_: DisconnectionCompleteCallBackProcess(), status=%u, reason=%u\n", status, reason);
274 // destruct
275 if (status == 0) {
276 std::unique_lock<std::mutex> lock(mutex_);
277 auto iter = connectionHandles_.find(connectionHandle);
278 if (iter != connectionHandles_.end()) {
279 auto its = powerDevices_.find(iter->second);
280 if (its != powerDevices_.end()) {
281 powerDevices_.erase(its);
282 }
283 LOG_DEBUG("PM_: DisconnectionCompleteCallBackProcess(), delete powerDevices, addr=%{public}s\n",
284 GetEncryptAddr(iter->second.GetAddress()).c_str());
285 connectionHandles_.erase(iter);
286 }
287 }
288 }
289
DisconnectionCompleteCallBack(uint8_t status,uint16_t connectionHandle,uint8_t reason,void * context)290 void PowerManager::impl::DisconnectionCompleteCallBack(
291 uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context)
292 {
293 static_cast<PowerManager*>(context)
294 ->pimpl->dispatcher_.PostTask(std::bind(&PowerManager::impl::DisconnectionCompleteCallBackProcess,
295 static_cast<PowerManager*>(context)->pimpl.get(),
296 status,
297 connectionHandle,
298 reason));
299 }
300 } // namespace bluetooth