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