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