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_state_machine.h"
17 #include <cstring>
18 #include "log.h"
19 #include "power_spec.h"
20
21 namespace OHOS {
22 namespace bluetooth {
Init(PowerDevice & pd)23 void PowerStateMachine::Init(PowerDevice &pd)
24 {
25 std::unique_ptr<utility::StateMachine::State> powerActiveState = std::make_unique<PowerActiveState>(*this, pd);
26 std::unique_ptr<utility::StateMachine::State> powerAaState =
27 std::make_unique<PowerActiveActivingState>(*this, pd, *powerActiveState.get());
28 std::unique_ptr<utility::StateMachine::State> powerAsState =
29 std::make_unique<PowerActiveSniffingState>(*this, pd, *powerActiveState.get());
30
31 std::unique_ptr<utility::StateMachine::State> powerSniffState = std::make_unique<PowerSniffState>(*this, pd);
32 std::unique_ptr<utility::StateMachine::State> powerSaState =
33 std::make_unique<PowerSniffActivingState>(*this, pd, *powerSniffState.get());
34 std::unique_ptr<utility::StateMachine::State> powerSsState =
35 std::make_unique<PowerSniffSniffingState>(*this, pd, *powerSniffState.get());
36
37 Move(powerActiveState);
38 Move(powerAaState);
39 Move(powerAsState);
40
41 Move(powerSniffState);
42 Move(powerSaState);
43 Move(powerSsState);
44
45 InitState(ACTIVE_STATE);
46 }
47
Entry()48 void PowerActiveState::Entry()
49 {
50 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
51 }
52
Exit()53 void PowerActiveState::Exit()
54 {
55 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
56 }
57
Dispatch(const utility::Message & msg)58 bool PowerActiveState::Dispatch(const utility::Message &msg)
59 {
60 switch (msg.what_) {
61 case PowerStateMachine::MSG_PM_MODE_CHANGE_SNIFF: {
62 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
63 Transition(SNIFF_STATE);
64 return true;
65 }
66 case PowerStateMachine::MSG_PM_SET_SNIFF: {
67 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
68 Transition(ACTIV_SNIFFING_STATE);
69 return true;
70 }
71 default:
72 return false;
73 }
74 }
75
Entry()76 void PowerActiveActivingState::Entry()
77 {
78 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
79 int exitSniffRet = pd_.BtmExitSniffMode();
80 LOG_DEBUG("PM_: BtmExitSniffMode ret val: %{public}d\n", exitSniffRet);
81 }
82
Exit()83 void PowerActiveActivingState::Exit()
84 {
85 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
86 }
87
Dispatch(const utility::Message & msg)88 bool PowerActiveActivingState::Dispatch(const utility::Message &msg)
89 {
90 switch (msg.what_) {
91 case PowerStateMachine::MSG_PM_MODE_CHANGE_ACTIVE: {
92 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
93 Transition(ACTIVE_STATE);
94 return true;
95 }
96 case PowerStateMachine::MSG_PM_MODE_CHANGE_SNIFF: {
97 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
98 return false;
99 }
100 case PowerStateMachine::MSG_PM_SET_ACTIVE: {
101 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
102 return true;
103 }
104 case PowerStateMachine::MSG_PM_SET_SNIFF: {
105 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
106 Transition(ACTIV_SNIFFING_STATE);
107 return true;
108 }
109 default:
110 return false;
111 }
112 }
113
Entry()114 void PowerActiveSniffingState::Entry()
115 {
116 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
117 auto powerLevel = pd_.GetRequestPowerLevel();
118 auto controlPowerLevel = pd_.GetControlPowerLevel();
119 if (powerLevel.first != PowerSsrLevel::NO_ACTION && powerLevel.first != controlPowerLevel.first) {
120 int ssrRet = pd_.BtmSetSniffSubrating(PowerSpec::GetPowerSsrParam(powerLevel.first));
121 LOG_DEBUG("PM_: BtmSetSniffSubrating ret val: %{public}d\n", ssrRet);
122 } else if (powerLevel.second != PowerModeLevel::NO_ACTION && powerLevel.second != controlPowerLevel.second) {
123 int sniffRet = pd_.BtmEnterSniffMode(PowerSpec::GetPowerParam(powerLevel.second));
124 LOG_DEBUG("PM_: BtmEnterSniffMode ret val: %{public}d\n", sniffRet);
125 } else {
126 }
127 }
128
Exit()129 void PowerActiveSniffingState::Exit()
130 {
131 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
132 }
133
Dispatch(const utility::Message & msg)134 bool PowerActiveSniffingState::Dispatch(const utility::Message &msg)
135 {
136 switch (msg.what_) {
137 case PowerStateMachine::MSG_PM_MODE_CHANGE_ACTIVE: {
138 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
139 Transition(ACTIVE_STATE);
140 return true;
141 }
142 case PowerStateMachine::MSG_PM_MODE_CHANGE_SNIFF: {
143 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
144 return false;
145 }
146 case PowerStateMachine::MSG_PM_SET_ACTIVE: {
147 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
148 Transition(ACTIV_ACTIVING_STATE);
149 return true;
150 }
151 case PowerStateMachine::MSG_PM_SET_SNIFF: {
152 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
153 auto powerLevel = pd_.GetRequestPowerLevel();
154 auto controlPowerLevel = pd_.GetControlPowerLevel();
155 if (powerLevel != controlPowerLevel) {
156 if (powerLevel.first != PowerSsrLevel::NO_ACTION && powerLevel.first != controlPowerLevel.first) {
157 int ssrRet = pd_.BtmSetSniffSubrating(PowerSpec::GetPowerSsrParam(powerLevel.first));
158 LOG_DEBUG("PM_: BtmSetSniffSubrating ret val: %{public}d\n", ssrRet);
159 } else if (powerLevel.second != PowerModeLevel::NO_ACTION &&
160 powerLevel.second != controlPowerLevel.second) {
161 int sniffRet = pd_.BtmEnterSniffMode(PowerSpec::GetPowerParam(powerLevel.second));
162 LOG_DEBUG("PM_: BtmEnterSniffMode ret val: %{public}d\n", sniffRet);
163 } else {
164 LOG_DEBUG("PM_: nothing to do in PowerActiveSniffingState while receive message MSG_PM_SET_SNIFF");
165 }
166 }
167 return true;
168 }
169 case PowerStateMachine::MSG_PM_SET_SUBRATING_COMPLETE: {
170 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_SUBRATING_COMPLETE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
171 auto powerLevel = pd_.GetRequestPowerLevel();
172 auto controlPowerLevel = pd_.GetControlPowerLevel();
173 if (powerLevel.second != PowerModeLevel::NO_ACTION && powerLevel.second != controlPowerLevel.second) {
174 int sniffRet = pd_.BtmEnterSniffMode(PowerSpec::GetPowerParam(powerLevel.second));
175 LOG_DEBUG("PM_: BtmEnterSniffMode ret val: %{public}d\n", sniffRet);
176 } else {
177 Transition(SNIFF_STATE);
178 }
179 return true;
180 }
181 default:
182 return false;
183 }
184 }
185
Entry()186 void PowerSniffState::Entry()
187 {
188 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
189 }
190
Exit()191 void PowerSniffState::Exit()
192 {
193 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
194 }
195
Dispatch(const utility::Message & msg)196 bool PowerSniffState::Dispatch(const utility::Message &msg)
197 {
198 switch (msg.what_) {
199 case PowerStateMachine::MSG_PM_MODE_CHANGE_ACTIVE: {
200 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
201 Transition(ACTIVE_STATE);
202 return true;
203 }
204 case PowerStateMachine::MSG_PM_SET_SNIFF: {
205 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
206 if (pd_.GetControlPowerLevel() != pd_.GetRequestPowerLevel()) {
207 Transition(SNIFF_SNIFFING_STATE);
208 LOG_DEBUG("PM_: %{public}s: requestPowerLevel = %{public}d, controlPowerLevel = %{public}d\n",
209 __PRETTY_FUNCTION__,
210 pd_.GetRequestPowerLevel().second,
211 pd_.GetControlPowerLevel().second);
212 LOG_DEBUG("PM_: %{public}s: requestSSRLevel = %{public}d, controlSSRLevel = %{public}d\n",
213 __PRETTY_FUNCTION__,
214 pd_.GetRequestPowerLevel().first,
215 pd_.GetControlPowerLevel().first);
216 }
217 return true;
218 }
219 case PowerStateMachine::MSG_PM_SET_ACTIVE: {
220 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
221 Transition(SNIFF_ACTIVING_STATE);
222 return true;
223 }
224 default:
225 return false;
226 }
227 }
228
Entry()229 void PowerSniffActivingState::Entry()
230 {
231 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
232 int exitSniffRet = pd_.BtmExitSniffMode();
233 LOG_DEBUG("PM_: BtmExitSniffMode ret val: %{public}d\n", exitSniffRet);
234 }
235
Exit()236 void PowerSniffActivingState::Exit()
237 {
238 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
239 }
240
Dispatch(const utility::Message & msg)241 bool PowerSniffActivingState::Dispatch(const utility::Message &msg)
242 {
243 switch (msg.what_) {
244 case PowerStateMachine::MSG_PM_MODE_CHANGE_ACTIVE: {
245 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
246 return false;
247 }
248 case PowerStateMachine::MSG_PM_MODE_CHANGE_SNIFF: {
249 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_MODE_CHANGE_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
250 Transition(SNIFF_STATE);
251 return true;
252 }
253 case PowerStateMachine::MSG_PM_SET_ACTIVE: {
254 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_ACTIVE line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
255 return true;
256 }
257 case PowerStateMachine::MSG_PM_SET_SNIFF: {
258 LOG_DEBUG("PM_: %{public}s, msg: MSG_PM_SET_SNIFF line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
259 Transition(SNIFF_SNIFFING_STATE);
260 LOG_DEBUG("PM_: %{public}s: requestPowerLevel = %{public}d, controlPowerLevel = %{public}d\n",
261 __PRETTY_FUNCTION__,
262 pd_.GetRequestPowerLevel().second,
263 pd_.GetControlPowerLevel().second);
264 LOG_DEBUG("PM_: %{public}s: requestSSRLevel = %{public}d, controlSSRLevel = %{public}d\n",
265 __PRETTY_FUNCTION__,
266 pd_.GetRequestPowerLevel().first,
267 pd_.GetControlPowerLevel().first);
268 return true;
269 }
270 default:
271 return false;
272 }
273 }
274
Entry()275 void PowerSniffSniffingState::Entry()
276 {
277 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
278 auto powerLevel = pd_.GetRequestPowerLevel();
279 auto controlPowerLevel = pd_.GetControlPowerLevel();
280 if (powerLevel.first != PowerSsrLevel::NO_ACTION && powerLevel.first != controlPowerLevel.first) {
281 int ssrRet = pd_.BtmSetSniffSubrating(PowerSpec::GetPowerSsrParam(powerLevel.first));
282 LOG_DEBUG("PM_: BtmSetSniffSubrating ret val: %{public}d\n", ssrRet);
283 } else if (powerLevel.second != PowerModeLevel::NO_ACTION && powerLevel.second != controlPowerLevel.second) {
284 LOG_DEBUG("PM_: %{public}s: requestSniffLevel != controlLevel, request sniff level = %{public}d, controlLevel = %{public}d\n",
285 __PRETTY_FUNCTION__,
286 powerLevel.second,
287 controlPowerLevel.second);
288 } else {
289 LOG_DEBUG("PM_: nothing to do in PowerSniffSniffingState entry");
290 }
291 }
292
Exit()293 void PowerSniffSniffingState::Exit()
294 {
295 LOG_DEBUG("PM_: %{public}s, line: %{public}d\n", __PRETTY_FUNCTION__, __LINE__);
296 }
297
Dispatch(const utility::Message & msg)298 bool PowerSniffSniffingState::Dispatch(const utility::Message &msg)
299 {
300 LOG_DEBUG("PM_: %{public}s, line: %{public}d, msg: %{public}d\n", __PRETTY_FUNCTION__, __LINE__, msg.what_);
301 switch (msg.what_) {
302 case PowerStateMachine::MSG_PM_MODE_CHANGE_ACTIVE: {
303 return false;
304 }
305 case PowerStateMachine::MSG_PM_MODE_CHANGE_SNIFF: {
306 Transition(SNIFF_STATE);
307 return true;
308 }
309 case PowerStateMachine::MSG_PM_SET_ACTIVE: {
310 Transition(SNIFF_ACTIVING_STATE);
311 return true;
312 }
313 case PowerStateMachine::MSG_PM_SET_SNIFF: {
314 auto powerLevel = pd_.GetRequestPowerLevel();
315 auto controlPowerLevel = pd_.GetControlPowerLevel();
316 if (powerLevel != controlPowerLevel) {
317 if (powerLevel.first != PowerSsrLevel::NO_ACTION && powerLevel.first != controlPowerLevel.first) {
318 pd_.BtmSetSniffSubrating(PowerSpec::GetPowerSsrParam(powerLevel.first));
319 } else if (powerLevel.second != PowerModeLevel::NO_ACTION &&
320 powerLevel.second != controlPowerLevel.second) {
321 LOG_DEBUG(
322 "PM_: %{public}s: requestSniffLevel != controlLevel, request sniff level = %{public}d, controlLevel = %{public}d\n",
323 __PRETTY_FUNCTION__, powerLevel.second, controlPowerLevel.second);
324 } else {
325 }
326 }
327 return true;
328 }
329 case PowerStateMachine::MSG_PM_SET_SUBRATING_COMPLETE: {
330 auto powerLevel = pd_.GetRequestPowerLevel();
331 auto controlPowerLevel = pd_.GetControlPowerLevel();
332 if (powerLevel.second != PowerModeLevel::NO_ACTION && powerLevel.second != controlPowerLevel.second) {
333 LOG_DEBUG("PM_: %{public}s: requestSniffLevel != controlLevel, request sniff level = %{public}d, controlLevel = %{public}d\n",
334 __PRETTY_FUNCTION__, powerLevel.second, controlPowerLevel.second);
335 } else {
336 Transition(SNIFF_STATE);
337 }
338 return true;
339 }
340 default:
341 return false;
342 }
343 }
344 } // namespace bluetooth
345 } // namespace OHOS