• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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