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_HF_STATEMACHINE_H
17 #define HFP_HF_STATEMACHINE_H
18 
19 #include <list>
20 #include <memory>
21 #include <string>
22 
23 #include "hfp_hf_call_manager.h"
24 #include "hfp_hf_defines.h"
25 #include "hfp_hf_message.h"
26 #include "hfp_hf_profile.h"
27 #include "state_machine.h"
28 #include "timer.h"
29 
30 namespace OHOS {
31 namespace bluetooth {
32 /**
33  * @brief Class for HF state machine.
34  */
35 class HfpHfStateMachine : public utility::StateMachine {
36 public:
37     /**
38      * @brief Construct a new HfpHfStateMachine object.
39      *
40      * @param address Device address.
41      */
42     explicit HfpHfStateMachine(const std::string &address);
43 
44     /**
45      * @brief Destroy the HfpHfStateMachine object.
46      */
47     ~HfpHfStateMachine() = default;
48 
49     /**
50      * @brief Initialise the state machine.
51      */
52     void Init();
53 
54     /**
55      * @brief Get the IsInbandRing flag.
56      *
57      * @return Returns isInBandRing flag.
58      */
59     bool GetIsInbandRing() const;
60 
61     /**
62      * @brief Get the volume stored in state machine.
63      *
64      * @return Returns the volume stored in state machine.
65      */
66     int GetVolume() const;
67 
68     /**
69      * @brief Get the State Int object.
70      *
71      * @return Returns the state number.
72      */
73     int GetDeviceStateInt() const;
74 
75     /**
76      * @brief Get the current call list.
77      *
78      * @return Returns the current call list.
79      */
80     std::vector<HandsFreeUnitCalls> GetCurrentCallList();
81 
82     /**
83      * @brief Process interactive event from profile.
84      *
85      * @param event The event from profile.
86      */
87     void ProcessInteractiveEvent(const HfpHfMessage &event);
88 
89     /**
90      * @brief Process accept call event from service.
91      *
92      * @param flag Accept call flag.
93      */
94     void ProcessAcceptCall(int flag);
95 
96     /**
97      * @brief Process hold call event from service.
98      */
99     void ProcessHoldCall();
100 
101     /**
102      * @brief Process reject call event from service.
103      */
104     void ProcessRejectCall();
105 
106     /**
107      * @brief Process send key pressed event.
108      *
109      */
110     void PrecessSendKeyPressed();
111 
112     /**
113      * @brief Process handle incoming call event from service.
114      *
115      * @param flag Handle call flag.
116      */
117     void ProcessHandleIncomingCall(int flag);
118 
119     /**
120      * @brief Process handle incoming call event from service.
121      *
122      * @param flag Handle call flag.
123      * @param index call index
124      */
125     void ProcessHandleMultiCall(int flag, int index);
126 
127     /**
128      * @brief Process dial last number event from service.
129      *
130      */
131     void ProcessDialLastNumber();
132 
133     /**
134      * @brief Process dial memory number event from service.
135      *
136      * @param index Memory number index
137      */
138     void ProcessDialMemory(int index);
139 
140     /**
141      * @brief Process send voice tag number event from service.
142      *
143      * @param index voice tag index
144      */
145     void ProcessSendVoiceTag(int index);
146 
147     /**
148      * @brief Process finish call event from service.
149      *
150      * @param event The finish call event.
151      */
152     void ProcessFinishCall(const HfpHfMessage &event);
153 
154     /**
155      * @brief Process dial call event from service.
156      *
157      * @param event The dial call event.
158      */
159     void ProcessDialCall(const HfpHfMessage &event);
160 
161     /**
162      * @brief Process open voice recognition event from service.
163      */
164     void ProcessOpenVoiceRecognition();
165 
166     /**
167      * @brief Process close voice recognition event from service.
168      */
169     void ProcessCloseVoiceRecognition();
170 
171     /**
172      * @brief Get the voice recognition state.
173      *
174      * @return Returns the voice recognition state.
175      */
176     int GetOpenVoiceRecognitionState() const;
177 
178     /**
179      * @brief Add the deferred message.
180      *
181      * @param msg The message.
182      */
183     void AddDeferredMessage(const HfpHfMessage &msg);
184 
185     /**
186      * @brief Process the deferred message.
187      */
188     void ProcessDeferredMessage();
189 
190     /**
191      * @brief Get the service event name.
192      *
193      * @param what Service event number.
194      * @return Returns service event string name.
195      */
196     static std::string GetEventName(int what);
197 
198     /**
199      * @brief Get the service interactive event type name.
200      *
201      * @param type Interactive event type number.
202      * @return Returns interactive event type string name.
203      */
204     std::string GetInteractiveEventType(int type) const;
205 
206     /**
207      * @brief Notify the state change.
208      */
209     void NotifyStateTransitions();
210 
211     /**
212      * @brief the state change from panrent state to child state.
213      *
214      * @param fromState The previous state.
215      * @param toState The current state
216      */
217     void NotifyChildStateToParentState(int fromState, int toState);
218 
219     /**
220      * @brief Process audio disconnected event.
221      */
222     void ProcessAudioDisconnected();
223 
224     /**
225      * @brief Start the connection timer.
226      */
227     void StartConnectionTimer() const;
228 
229     /**
230      * @brief Stop the connection timer.
231      */
232     void StopConnectionTimer() const;
233 
234     /**
235      * @brief Connection timeout handler.
236      */
237     void ConnectionTimeout() const;
238 
239     /**
240      * @brief synchronize the sco event when sco is on.
241      *
242      * @param state : The state of the sco.
243      */
244     void SyncScoEvents(int state);
245 
246     /**
247      * @brief Check if current statemachine is removing.
248      *
249      * @return Returns <b>true</b> if the statemachine is removing; returns <b>false</b> if not.
250      */
251     bool IsRemoving() const;
252 
253     /**
254      * @brief Mark statemachine removing.
255      *
256      * @param isRemoving removing mark.
257      */
258     void SetRemoving(bool isRemoving);
259 
260     /**
261      * @brief Process Network state change from profile.
262      *
263      * @param event Network state change event.
264      */
265     void ProcessNetworkStateEvent(const HfpHfMessage &event);
266 
267     /**
268      * @brief Process Network roam change from profile.
269      *
270      * @param event Network roam change event.
271      */
272     void ProcessNetworkRoamEvent(const HfpHfMessage &event);
273 
274     /**
275      * @brief Process Network signal change from profile.
276      *
277      * @param event Network signal change event.
278      */
279     void ProcessNetworkSignalEvent(const HfpHfMessage &event);
280 
281     /**
282      * @brief Process Battery level change from profile.
283      *
284      * @param event Battery level change event.
285      */
286     void ProcessBatteryLevelEvent(const HfpHfMessage &event);
287 
288     /**
289      * @brief Process Battery level change from profile.
290      *
291      * @param event Battery level change event.
292      */
293     void ProcessOperatorEvent(const HfpHfMessage &event);
294 
295     /**
296      * @brief Process Call indicator change event.
297      *
298      * @param event Call indicator change event.
299      */
300     void ProcessCallIndicatorEvent(const HfpHfMessage &event);
301 
302     /**
303      * @brief Process Call indicator change event.
304      *
305      * @param event Call indicator change event.
306      */
307     void ProcessCurrentCallEvent(const HfpHfMessage &event) const;
308 
309     /**
310      * @brief Process volume change event.
311      *
312      * @param event Volume change event.
313      */
314     void ProcessSetVolumeEvent(const HfpHfMessage &event) const;
315 
316     /**
317      * @brief Process Subscriber number event.
318      *
319      * @param event Subscriber number event.
320      */
321     void ProcessSubscriberNumberEvent(const HfpHfMessage &event);
322 
323     /**
324      * @brief Process Inband ring event.
325      *
326      * @param event Inband ring event.
327      */
328     void ProcessInbandRingEvent(const HfpHfMessage &event);
329 
330     /**
331      * @brief Process voice recognition change event.
332      *
333      * @param event Voice recognition change event.
334      */
335     void ProcessVrChangedEvent(const HfpHfMessage &event);
336 
337     /**
338      * @brief Process open voice recognition result event.
339      *
340      * @param event Open voice recognition result event.
341      */
342     void ProcessOpenVrResultEvent(const HfpHfMessage &event);
343 
344     /**
345      * @brief Process close voice recognition result event.
346      *
347      * @param event Close voice recognition result event.
348      */
349     void ProcessCloseVrResultEvent(const HfpHfMessage &event);
350 
351     /**
352      * @brief Notify the status of the voice recognition.
353      *
354      * @param status The status of the voice recognition.
355      */
356     void NotifyVoiceRecognitionStatusChanged(int status);
357 
358     /**
359      * @brief Route hf audio state.
360      *
361      * @param flag The state to toute.
362      */
363     void routeHfAudio(bool state);
364 
365     inline static const std::string DISCONNECTED = "Disconnected";
366     inline static const std::string CONNECTING = "Connecting";
367     inline static const std::string DISCONNECTING = "Disconnecting";
368     inline static const std::string CONNECTED = "Connected";
369     inline static const std::string AUDIO_CONNECTING = "AudioConnecting";
370     inline static const std::string AUDIO_DISCONNECTING = "AudioDisconnecting";
371     inline static const std::string AUDIO_CONNECTED = "AudioConnected";
372 
373 private:
374     std::string address_;
375     HfpHfProfile profile_;
376     std::unique_ptr<HfpHfCallManager> calls_ {nullptr};
377     bool isInBandRing_ {false};
378     int networkState_ {0};
379     int networkTRoam_ {0};
380     int networkSignal_ {0};
381     int batteryLevel_ {0};
382     int volume_ {0};
383     std::string operatorName_ {""};
384     std::string subscriberNumber_ {""};
385     std::list<HfpHfMessage> deferMsgs_ {};
386     int preState_ {0};
387     int voiceRecognitionStatus_ {HFP_HF_VR_STATE_CLOSED};
388     std::unique_ptr<utility::Timer> connTimer_ {nullptr};
389     inline static const int CONNECTION_TIMEOUT_MS {60000};  // 60s
390     bool isRemoving_ {false};
391     bool isAudioRouted_ {false};
392 
393     BT_DISALLOW_COPY_AND_ASSIGN(HfpHfStateMachine);
394 };
395 
396 class HfpHfState : public utility::StateMachine::State {
397 public:
HfpHfState(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile,int stateInt,utility::StateMachine::State & parent)398     HfpHfState(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile, int stateInt,
399         utility::StateMachine::State &parent)
400         : State(name, statemachine, parent), profile_(profile),
401         stateInt_(stateInt), stateMachine_((HfpHfStateMachine &)statemachine) {}
402 
HfpHfState(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile,int stateInt)403     HfpHfState(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile, int stateInt)
404         : State(name, statemachine), profile_(profile),
405         stateInt_(stateInt), stateMachine_((HfpHfStateMachine &)statemachine) {}
406 
~HfpHfState()407     virtual ~HfpHfState()
408     {}
GetStateInt()409     int GetStateInt() const
410     {
411         return stateInt_;
412     }
413 
414 protected:
415     HfpHfProfile& profile_;
416     int stateInt_ {HFP_HF_STATE_DISCONNECTED};
417     HfpHfStateMachine &stateMachine_;
418 };
419 
420 class HfpHfDisconnected : public HfpHfState {
421 public:
HfpHfDisconnected(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile)422     HfpHfDisconnected(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile)
423         : HfpHfState(name, statemachine, profile, HFP_HF_STATE_DISCONNECTED)
424     {}
425     ~HfpHfDisconnected() override = default;
426     void Entry() override;
427     void Exit() override;
428     bool Dispatch(const utility::Message &msg) override;
429 
430 private:
431     bool isReentry_ {false};
432 };
433 
434 class HfpHfConnecting : public HfpHfState {
435 public:
HfpHfConnecting(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile)436     HfpHfConnecting(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile)
437         : HfpHfState(name, statemachine, profile, HFP_HF_STATE_CONNECTING)
438     {}
439     ~HfpHfConnecting() override = default;
440     void Entry() override;
441     void Exit() override;
442     bool Dispatch(const utility::Message &msg) override;
443 };
444 
445 class HfpHfDisconnecting : public HfpHfState {
446 public:
HfpHfDisconnecting(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile)447     HfpHfDisconnecting(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile)
448         : HfpHfState(name, statemachine, profile, HFP_HF_STATE_DISCONNECTING)
449     {}
450     ~HfpHfDisconnecting() override = default;
451     void Entry() override;
452     void Exit() override;
453     bool Dispatch(const utility::Message &msg) override;
454 };
455 
456 class HfpHfConnected : public HfpHfState {
457 public:
HfpHfConnected(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile)458     HfpHfConnected(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile)
459         : HfpHfState(name, statemachine, profile, HFP_HF_STATE_CONNECTED)
460     {}
461     ~HfpHfConnected() override = default;
462     void Entry() override;
Exit()463     void Exit() override
464     {}
465     bool Dispatch(const utility::Message &msg) override;
466 };
467 
468 class HfpHfAudioConnecting : public HfpHfState {
469 public:
HfpHfAudioConnecting(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile,utility::StateMachine::State & parent)470     HfpHfAudioConnecting(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile,
471         utility::StateMachine::State &parent)
472         : HfpHfState(name, statemachine, profile, HFP_HF_AUDIO_STATE_CONNECTING, parent)
473     {}
474     ~HfpHfAudioConnecting() override = default;
475     void Entry() override;
476     void Exit() override;
477     bool Dispatch(const utility::Message &msg) override;
478 };
479 
480 class HfpHfAudioDisconnecting : public HfpHfState {
481 public:
HfpHfAudioDisconnecting(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile,utility::StateMachine::State & parent)482     HfpHfAudioDisconnecting(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile,
483         utility::StateMachine::State &parent)
484         : HfpHfState(name, statemachine, profile, HFP_HF_AUDIO_STATE_DISCONNECTING, parent)
485     {}
486     ~HfpHfAudioDisconnecting() override = default;
487     void Entry() override;
488     void Exit() override;
489     bool Dispatch(const utility::Message &msg) override;
490 };
491 
492 class HfpHfAudioConnected : public HfpHfState {
493 public:
HfpHfAudioConnected(const std::string & name,utility::StateMachine & statemachine,HfpHfProfile & profile,utility::StateMachine::State & parent)494     HfpHfAudioConnected(const std::string &name, utility::StateMachine &statemachine, HfpHfProfile &profile,
495         utility::StateMachine::State &parent)
496         : HfpHfState(name, statemachine, profile, HFP_HF_AUDIO_STATE_CONNECTED, parent)
497     {}
498     ~HfpHfAudioConnected() override = default;
499     void Entry() override;
Exit()500     void Exit() override
501     {}
502     bool Dispatch(const utility::Message &msg) override;
503 
504 private:
505     void ProcessDisconnect(const HfpHfMessage &event);
506 };
507 }  // namespace bluetooth
508 }  // namespace OHOS
509 #endif // HFP_HF_STATEMACHINE_H