1 /*
2  * Copyright (C) 2021-2022 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 #ifndef HFP_AG_STATEMACHINE_H
17 #define HFP_AG_STATEMACHINE_H
18 
19 #include <list>
20 #include <memory>
21 #include <string>
22 
23 #include "hfp_ag_message.h"
24 #include "hfp_ag_profile.h"
25 #include "hfp_ag_system_event_processer.h"
26 #include "state_machine.h"
27 
28 namespace OHOS {
29 namespace bluetooth {
30 /**
31  * @brief Class for AG state machine.
32  */
33 class HfpAgStateMachine : public utility::StateMachine {
34 public:
35     /**
36      * @brief Construct a new HfpAgStateMachine object.
37      *
38      * @param address Device address.
39      */
40     explicit HfpAgStateMachine(const std::string &address);
41 
42     /**
43      * @brief Destroy the HfpAgStateMachine object.
44      */
45     ~HfpAgStateMachine() = default;
46 
47     /**
48      * @brief Initialise the state machine.
49      */
50     void Init();
51 
52     /**
53      * @brief Get the State Int object.
54      *
55      * @return Returns the state number.
56      */
57     int GetStateInt() const;
58 
59     /**
60      * @brief Get the device address.
61      *
62      * @return Returns the device address.
63      */
64     std::string GetDeviceAddr() const;
65 
66     /**
67      * @brief Add the deferred message.
68      *
69      * @param msg The message.
70      */
71     void AddDeferredMessage(const HfpAgMessage &msg);
72 
73     /**
74      * @brief Process the deferred message.
75      */
76     void ProcessDeferredMessage();
77 
78     /**
79      * @brief Notify the state change.
80      */
81     void NotifyStateTransitions();
82 
83     /**
84      * @brief the state change from panrent state to child state.
85      *
86      * @param fromState The previous state.
87      * @param toState The current state.
88      * @param reason Reason for change status.
89      */
90     void NotifyChildStateToParentState(int fromState, int toState, int reason = 0);
91 
92     /**
93      * @brief Process audio disconnected event.
94      */
95     void ProcessAudioDisconnected(int reason);
96 
97     /**
98      * @brief Start the connection timer.
99      */
100     void StartConnectionTimer() const;
101 
102     /**
103      * @brief Stop the connection timer.
104      */
105     void StopConnectionTimer() const;
106 
107     /**
108      * @brief Connection timeout handler.
109      */
110     void ConnectionTimeout() const;
111 
112     /**
113      * @brief Get the service event name.
114      *
115      * @param what Service event number.
116      * @return Returns the service event string name.
117      */
118     static std::string GetEventName(int what);
119 
120     /**
121      * @brief Check if current statemachine is removing.
122      *
123      * @return Returns <b>true</b> if the statemachine is removing; returns <b>false</b> if not.
124      */
125     bool IsRemoving() const;
126 
127     /**
128      * @brief Mark statemachine removing.
129      *
130      * @param isRemoving removing mark.
131      */
132     void SetRemoving(bool isRemoving);
133 
134     void ProcessKeyPressed(const RawAddress &device, const int &phoneState) const;
135 
136     inline static const std::string DISCONNECTED = "Disconnected";
137     inline static const std::string CONNECTING = "Connecting";
138     inline static const std::string DISCONNECTING = "Disconnecting";
139     inline static const std::string CONNECTED = "Connected";
140     inline static const std::string AUDIO_CONNECTING = "AudioConnecting";
141     inline static const std::string AUDIO_DISCONNECTING = "AudioDisconnecting";
142     inline static const std::string AUDIO_CONNECTED = "AudioConnected";
143 
144 private:
145     std::string address_;
146     HfpAgProfile profile_;
147     HfpAgSystemEventProcesser eventProcessor_;
148     std::list<HfpAgMessage> deferMsgs_ {};
149     int preState_ {HFP_AG_STATE_DISCONNECTED};
150     std::unique_ptr<utility::Timer> connTimer_ {nullptr};
151     inline static const int CONNECTION_TIMEOUT_MS {60000};  // 60s
152     bool isRemoving_ {false};
153 
154     BT_DISALLOW_COPY_AND_ASSIGN(HfpAgStateMachine);
155 };
156 
157 class HfpAgState : public utility::StateMachine::State {
158 public:
159     struct HfpAgSmInfo {
HfpAgSmInfoHfpAgSmInfo160         HfpAgSmInfo(const std::string &name, utility::StateMachine& statemachine)
161             : name_(name), sm_(statemachine)
162         {}
163         const std::string& name_;
164         utility::StateMachine& sm_;
165     };
166 
HfpAgState(HfpAgSmInfo stu,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch,int stateInt,utility::StateMachine::State & parent)167     HfpAgState(HfpAgSmInfo stu, HfpAgProfile &profile,
168         HfpAgSystemEventProcesser &eventDispatch, int stateInt,
169         utility::StateMachine::State &parent)
170         : State(stu.name_, stu.sm_, parent),
171           profile_(profile),
172           eventProcessor_(eventDispatch),
173           stateInt_(stateInt),
174           stateMachine_(static_cast<HfpAgStateMachine &>(stu.sm_))
175     {}
176 
HfpAgState(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch,int stateInt)177     HfpAgState(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
178         HfpAgSystemEventProcesser &eventDispatch, int stateInt)
179         : State(name, statemachine),
180           profile_(profile),
181           eventProcessor_(eventDispatch),
182           stateInt_(stateInt),
183           stateMachine_((HfpAgStateMachine &)statemachine)
184     {}
~HfpAgState()185     virtual ~HfpAgState()
186     {}
GetStateInt()187     int GetStateInt() const
188     {
189         return stateInt_;
190     }
191 
192 protected:
193     HfpAgProfile& profile_;
194     int callState_ = 0;
195     HfpAgSystemEventProcesser &eventProcessor_;
196     int stateInt_ {HFP_AG_STATE_DISCONNECTED};
197     HfpAgStateMachine &stateMachine_;
198 };
199 
200 class HfpAgDisconnected : public HfpAgState {
201 public:
HfpAgDisconnected(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch)202     HfpAgDisconnected(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
203         HfpAgSystemEventProcesser &eventDispatch)
204         : HfpAgState(name, statemachine, profile, eventDispatch, HFP_AG_STATE_DISCONNECTED)
205     {}
206     ~HfpAgDisconnected() override = default;
207     void Entry() override;
208     void Exit() override;
209     bool Dispatch(const utility::Message &msg) override;
210 
211 private:
212     bool isReentry_ {false};
213 };
214 
215 class HfpAgConnecting : public HfpAgState {
216 public:
HfpAgConnecting(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch)217     HfpAgConnecting(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
218         HfpAgSystemEventProcesser &eventDispatch)
219         : HfpAgState(name, statemachine, profile, eventDispatch, HFP_AG_STATE_CONNECTING)
220     {}
221     ~HfpAgConnecting() override = default;
222     void Entry() override;
223     void Exit() override;
224     bool Dispatch(const utility::Message &msg) override;
225 private:
226     int hspState_ = 1;
227 };
228 
229 class HfpAgDisconnecting : public HfpAgState {
230 public:
HfpAgDisconnecting(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch)231     HfpAgDisconnecting(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
232         HfpAgSystemEventProcesser &eventDispatch)
233         : HfpAgState(name, statemachine, profile, eventDispatch, HFP_AG_STATE_DISCONNECTING)
234     {}
235     ~HfpAgDisconnecting() override = default;
236     void Entry() override;
237     void Exit() override;
238     bool Dispatch(const utility::Message &msg) override;
239 };
240 
241 class HfpAgConnected : public HfpAgState {
242 public:
HfpAgConnected(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch)243     HfpAgConnected(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
244         HfpAgSystemEventProcesser &eventDispatch)
245         : HfpAgState(name, statemachine, profile, eventDispatch, HFP_AG_STATE_CONNECTED)
246     {}
247     ~HfpAgConnected() override = default;
248     void Entry() override;
Exit()249     void Exit() override
250     {}
251     bool Dispatch(const utility::Message &msg) override;
252 
253 private:
254     void ProcessVoiceRecognitionResult(int result);
255     void ProcessPhoneStateChange(const HfpAgMessage &event) const;
256     void ProcessResponseClcc(const HfpAgMessage &event) const;
257     void ProcessResponesOK() const;
258 };
259 
260 class HfpAgAudioConnecting : public HfpAgState {
261 public:
HfpAgAudioConnecting(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch,utility::StateMachine::State & parent)262     HfpAgAudioConnecting(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
263         HfpAgSystemEventProcesser &eventDispatch, utility::StateMachine::State &parent)
264         : HfpAgState(HfpAgSmInfo(name, statemachine), profile, eventDispatch, HFP_AG_AUDIO_STATE_CONNECTING, parent)
265     {}
266     ~HfpAgAudioConnecting() override = default;
267     void Entry() override;
268     void Exit() override;
269     bool Dispatch(const utility::Message &msg) override;
270 };
271 
272 class HfpAgAudioDisconnecting : public HfpAgState {
273 public:
HfpAgAudioDisconnecting(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch,utility::StateMachine::State & parent)274     HfpAgAudioDisconnecting(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
275         HfpAgSystemEventProcesser &eventDispatch, utility::StateMachine::State &parent)
276         : HfpAgState(HfpAgSmInfo(name, statemachine), profile, eventDispatch, HFP_AG_AUDIO_STATE_DISCONNECTING, parent)
277     {}
278     ~HfpAgAudioDisconnecting() override = default;
279     void Entry() override;
280     void Exit() override;
281     bool Dispatch(const utility::Message &msg) override;
282 };
283 
284 class HfpAgAudioConnected : public HfpAgState {
285 public:
HfpAgAudioConnected(const std::string & name,utility::StateMachine & statemachine,HfpAgProfile & profile,HfpAgSystemEventProcesser & eventDispatch,utility::StateMachine::State & parent)286     HfpAgAudioConnected(const std::string &name, utility::StateMachine &statemachine, HfpAgProfile &profile,
287         HfpAgSystemEventProcesser &eventDispatch, utility::StateMachine::State &parent)
288         : HfpAgState(HfpAgSmInfo(name, statemachine), profile, eventDispatch, HFP_AG_AUDIO_STATE_CONNECTED, parent)
289     {}
290     ~HfpAgAudioConnected() override = default;
291     void Entry() override;
Exit()292     void Exit() override
293     {}
294     bool Dispatch(const utility::Message &msg) override;
295 
296 private:
297     void ProcessDisconnect(const HfpAgMessage &event);
298     void ProcessSetVolume(const HfpAgMessage &event);
299 };
300 }  // namespace bluetooth
301 }  // namespace OHOS
302 #endif // HFP_AG_STATEMACHINE_H
303