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 A2DP_STATE_MACHINE_H
17 #define A2DP_STATE_MACHINE_H
18 
19 #include <cstdint>
20 #include <memory>
21 #include <string>
22 
23 #include "a2dp_avdtp.h"
24 #include "a2dp_def.h"
25 #include "bt_def.h"
26 #include "btstack.h"
27 #include "message.h"
28 #include "state_machine.h"
29 
30 namespace OHOS {
31 namespace bluetooth {
32 const std::string A2DP_PROFILE_IDLE = "A2dpStateIdle";
33 const std::string A2DP_PROFILE_CONFIG = "A2dpStateConfigure";
34 const std::string A2DP_PROFILE_OPENING = "A2dpStateOpening";
35 const std::string A2DP_PROFILE_OPEN = "A2dpStateOpen";
36 const std::string A2DP_PROFILE_STREAMING = "A2dpStateStreaming";
37 const std::string A2DP_PROFILE_CLOSING = "A2dpStateClosing";
38 
39 class A2dpStateIdle : public utility::StateMachine::State {
40 public:
41     /**
42      * @brief Construct a Idle State object.
43      * @param name State's name.
44      * @param stateMachine State is owned by which StateMachine.
45      * @since 6.0
46      */
A2dpStateIdle(const std::string & name,utility::StateMachine & stateMachine)47     A2dpStateIdle(const std::string &name, utility::StateMachine &stateMachine)
48         : utility::StateMachine::State(name, stateMachine)
49     {}
50 
51     /**
52      * @brief Destruct a Idle State object.
53      * @since 6.0
54      */
55     ~A2dpStateIdle() = default;
56 
57     /**
58      * @brief Operation should be executed when Entry the state.
59      * @since 6.0
60      */
61     void Entry();
62 
63     /**
64      * @brief Operation should be executed when Exit the state.
65      * @since 6.0
66      */
Exit()67     void Exit()
68     {}
69 
70     /**
71      * @brief Dispatch the message of profile peer.
72      * @param[in] The message of profile peer related
73      * @since 6.0
74      */
75     bool Dispatch(const utility::Message &msg);
76 
77 private:
78     /**
79      * @brief Process the result of signaling connect.
80      * @param[in] addr The address of peer device
81      * @param[in] role The role of local profile
82      * @param[in] errCode The error code of signaling connect
83      * @since 6.0
84      */
85     void ProcessDiscoverReq(BtAddr addr, uint8_t role, uint8_t errCode);
86 
87     /**
88      * @brief Process the failure of SDP.
89      * @param[in] addr The address of peer device
90      * @param[in] role The role of local profile
91      * @since 6.0
92      */
93     void ProcessSDPFailure(BtAddr addr, uint8_t role) const;
94 
95     /**
96      * @brief Process the indication of disconnection.
97      * @param[in] addr The address of peer device
98      * @param[in] handle The handle of stream
99      * @param[in] role The role of local profile
100      * @since 6.0
101      */
102     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
103 
104     /**
105      * @brief Process the requirement of disconnect.
106      * @param[in] addr The address of peer device
107      * @param[in] role The role of local profile
108      * @since 6.0
109      */
110     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
111 
112     /**
113      * @brief Process the timeout.
114      * @param[in] addr The address of peer device
115      * @param[in] role The role of local profile
116      * @since 6.0
117      */
118     void ProcessTimeout(BtAddr addr, uint8_t role);
119 
120     /**
121      * @brief Process the Indication of configure.
122      * @param[in] msgData The data of message
123      * @param[in] role The role of local profile
124      * @since 6.0
125      */
126     void ProcessSetConfigInd(A2dpAvdtMsgData msgData, uint8_t role);
127 
128     /**
129      * @brief Process the requirement of configure.
130      * @param[in] msgData The data of message
131      * @param[in] role The role of local profile
132      * @since 6.0
133      */
134     void ProcessSetConfigReq(A2dpAvdtMsgData msgData, uint8_t role);
135 
136     /**
137      * @brief Set current state
138      *
139      * @since 6.0
140      */
141     void SetStateName(std::string state);
142 
143     /**
144      * @brief Process the confirm of disconnection.
145      * @param[in] addr The address of peer device
146      * @param[in] handle The handle of stream
147      * @param[in] role The role of local profile
148      * @since 6.0
149      */
150     void ProcessDisconnectCfm(BtAddr addr, uint16_t handle, uint8_t role) const;
151 };
152 
153 class A2dpStateConfigure : public utility::StateMachine::State {
154 public:
155     /**
156      * @brief Construct a configure State object.
157      * @param name State's name.
158      * @param stateMachine State is owned by which StateMachine.
159      * @since 6.0
160      */
A2dpStateConfigure(const std::string & name,utility::StateMachine & stateMachine)161     A2dpStateConfigure(const std::string &name, utility::StateMachine &stateMachine)
162         : utility::StateMachine::State(name, stateMachine)
163     {}
164 
165     /**
166      * @brief Destruct a Configure object.
167      *
168      * @since 6.0
169      */
170     ~A2dpStateConfigure() = default;
171 
172     /**
173      * @brief Operation should be executed when Entry the state.
174      * @since 6.0
175      */
Entry()176     void Entry()
177     {}
178 
179     /**
180      * @brief Operation should be executed when Exit the state.
181      * @since 6.0
182      */
Exit()183     void Exit()
184     {}
185 
186     /**
187      * @brief Dispatch the message of profile peer.
188      * @param[in] The message of profile peer related
189      * @since 6.0
190      */
191     bool Dispatch(const utility::Message &msg);
192 
193 private:
194     /**
195      * @brief Process the Indication of configure.
196      * @param[in] msgData The data of message
197      * @param[in] role The role of local profile
198      * @since 6.0
199      */
200     void ProcessSetConfigInd(A2dpAvdtMsgData msgData, uint8_t role);
201 
202     /**
203      * @brief Process the requirement of disconnect.
204      * @param[in] addr The address of peer device
205      * @param[in] role The role of local profile
206      * @since 6.0
207      */
208     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
209 
210     /**
211      * @brief Process the indication of disconnection.
212      * @param[in] addr The address of peer device
213      * @param[in] handle The handle of stream
214      * @param[in] role The role of local profile
215      * @since 6.0
216      */
217     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
218 
219     /**
220      * @brief Process the Indication of configure.
221      * @param[in] msgData The data of message
222      * @param[in] role The role of local profile
223      * @since 6.0
224      */
225     void ProcessOpenInd(A2dpAvdtMsgData msgData, uint8_t role);
226 
227     /**
228      * @brief Process the requirement of open.
229      * @param[in] addr The address of peer device
230      * @param[in] handle The handle of stream
231      * @param[in] role The role of local profile
232      * @since 6.0
233      */
234     void ProcessOpenReq(BtAddr addr, uint16_t handle, uint8_t role);
235 
236     /**
237      * @brief Set current state
238      *
239      * @since 6.0
240      */
241     void SetStateName(std::string state);
242 
243     /**
244      * @brief Process the indication of delay reporting.
245      * @param[in] msgData The information of message
246      * @param[in] role The role of local profile
247      */
248     void ProcessDelayReportInd(A2dpAvdtMsgData msgData, uint8_t role) const;
249 };
250 
251 class A2dpStateOpening : public utility::StateMachine::State {
252 public:
253     /**
254      * @brief Construct a Opening State object.
255      * @param name State's name.
256      * @param stateMachine State is owned by which StateMachine.
257      * @since 6.0
258      */
A2dpStateOpening(const std::string & name,utility::StateMachine & stateMachine)259     A2dpStateOpening(const std::string &name, utility::StateMachine &stateMachine)
260         : utility::StateMachine::State(name, stateMachine)
261     {}
262     /**
263      * @brief Destruct a Opening object.
264      *
265      * @since 6.0
266      */
267     ~A2dpStateOpening() = default;
268 
269     /**
270      * @brief Operation should be executed when Entry the state.
271      * @since 6.0
272      */
Entry()273     void Entry()
274     {}
275 
276     /**
277      * @brief Operation should be executed when Exit the state.
278      * @since 6.0
279      */
Exit()280     void Exit()
281     {}
282 
283     /**
284      * @brief Dispatch the message of profile peer.
285      * @param[in] The message of profile peer related
286      * @since 6.0
287      */
288     bool Dispatch(const utility::Message &msg);
289 
290 private:
291     /**
292      * @brief Process the requirement of disconnect.
293      * @param[in] addr The address of peer device
294      * @param[in] role The role of local profile
295      * @since 6.0
296      */
297     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
298 
299     /**
300      * @brief Process the indication of disconnection.
301      * @param[in] addr The address of peer device
302      * @param[in] handle The handle of stream
303      * @param[in] role The role of local profile
304      * @since 6.0
305      */
306     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
307 
308     /**
309      * @brief Process the confirm of open.
310      * @param[in] msgData The data of message
311      * @param[in] role The role of local profile
312      * @since 6.0
313      */
314     void ProcessOpenCfm(A2dpAvdtMsgData msgData, uint8_t role);
315 
316     /**
317      * @brief Set current state
318      *
319      * @since 6.0
320      */
321     void SetStateName(std::string state);
322 
323     /**
324      * @brief Process the indication of delay reporting.
325      * @param[in] msgData The information of message
326      * @param[in] role The role of local profile
327      */
328     void ProcessDelayReportInd(A2dpAvdtMsgData msgData, uint8_t role) const;
329 };
330 
331 class A2dpStateOpen : public utility::StateMachine::State {
332 public:
333     /**
334      * @brief Construct a Open State object.
335      * @param name State's name.
336      * @param stateMachine State is owned by which StateMachine.
337      * @since 6.0
338      */
A2dpStateOpen(const std::string & name,utility::StateMachine & stateMachine)339     A2dpStateOpen(const std::string &name, utility::StateMachine &stateMachine)
340         : utility::StateMachine::State(name, stateMachine)
341     {}
342 
343     /**
344      * @brief Destruct a Open object.
345      *
346      * @since 6.0
347      */
348     ~A2dpStateOpen() = default;
349 
350     /**
351      * @brief Operation should be executed when Entry the state.
352      * @since 6.0
353      */
Entry()354     void Entry()
355     {}
356 
357     /**
358      * @brief Operation should be executed when Exit the state.
359      * @since 6.0
360      */
Exit()361     void Exit()
362     {}
363 
364     /**
365      * @brief Dispatch the message of profile peer.
366      * @param[in] The message of profile peer related
367      * @since 6.0
368      */
369     bool Dispatch(const utility::Message &msg);
370 
371 private:
372     /**
373      * @brief Process the timeout.
374      * @param[in] addr The address of peer device
375      * @param[in] role The role of local profile
376      * @since 6.0
377      */
378     void ProcessTimeout(BtAddr addr, uint8_t role);
379 
380     /**
381      * @brief Process the indication of start.
382      * @param[in] msgData The information of message
383      * @param[in] role The role of local profile
384      * @since 6.0
385      */
386     void ProcessStartInd(A2dpAvdtMsgData msgData, uint8_t role);
387 
388     /**
389      * @brief Process the confirm of start.
390      * @param[in] addr The address of peer device
391      * @param[in] role The role of local profile
392      * @since 6.0
393      */
394     void ProcessStartCfm(BtAddr addr, uint8_t role);
395 
396     /**
397      * @brief Process the indication of close.
398      * @param[in] msgData The information of message
399      * @param[in] role The role of local profile
400      * @since 6.0
401      */
402     void ProcessCloseInd(A2dpAvdtMsgData msgData, uint8_t role);
403 
404     /**
405      * @brief Process the confirm of close.
406      * @param[in] addr The address of peer device
407      * @param[in] role The role of local profile
408      * @since 6.0
409      */
410     void ProcessCloseCfm(BtAddr addr, uint8_t role);
411 
412     /**
413      * @brief Process the confirm of reconfigure.
414      * @param[in] addr The address of peer device
415      * @param[in] role The role of local profile
416      * @param[in] handle The stream handle
417      * @since 6.0
418      */
419     void ProcessReconfigCfm(BtAddr addr, uint8_t role, uint16_t handle);
420 
421     /**
422      * @brief Process the requirement of disconnect.
423      * @param[in] addr The address of peer device
424      * @param[in] role The role of local profile
425      * @since 6.0
426      */
427     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
428 
429     /**
430      * @brief Process the indication of disconnection.
431      * @param[in] addr The address of peer device
432      * @param[in] handle The handle of stream
433      * @param[in] role The role of local profile
434      * @since 6.0
435      */
436     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
437 
438     /**
439      * @brief Process the other cmd of open state.
440      * @param[in] msgData The information of message
441      * @param[in] role The role of local profile
442      * @since 6.0
443      */
444     void ProcessSubOpenState(A2dpAvdtMsgData msgData, uint8_t role, int cmd);
445 
446     /**
447      * @brief Set current state
448      *
449      * @since 6.0
450      */
451     void SetStateName(std::string state);
452 
453     /**
454      * @brief Process the indication of delay reporting.
455      * @param[in] msgData The information of message
456      * @param[in] role The role of local profile
457      */
458     void ProcessDelayReportInd(A2dpAvdtMsgData msgData, uint8_t role) const;
459 
460     uint8_t label_ = 0;
461 };
462 
463 class A2dpStateStreaming : public utility::StateMachine::State {
464 public:
465     /**
466      * @brief Construct a Streaming State object.
467      * @param name State's name.
468      * @param stateMachine State is owned by which StateMachine.
469      * @since 6.0
470      */
A2dpStateStreaming(const std::string & name,utility::StateMachine & stateMachine)471     A2dpStateStreaming(const std::string &name, utility::StateMachine &stateMachine)
472         : utility::StateMachine::State(name, stateMachine)
473     {}
474 
475     /**
476      * @brief Destruct a Streaming object.
477      *
478      * @since 6.0
479      */
480     ~A2dpStateStreaming() = default;
481 
482     /**
483      * @brief Operation should be executed when Entry the state.
484      * @since 6.0
485      */
486     void Entry();
487 
488     /**
489      * @brief Operation should be executed when Exit the state.
490      * @since 6.0
491      */
492     void Exit();
493 
494     /**
495      * @brief Dispatch the message of profile peer.
496      * @param[in] The message of profile peer related
497      * @since 6.0
498      */
499     bool Dispatch(const utility::Message &msg);
500 
501 private:
502     /**
503      * @brief Process the confirm of close.
504      * @param[in] addr The address of peer device
505      * @param[in] role The role of local profile
506      * @since 6.0
507      */
508     void ProcessCloseCfm(BtAddr addr, uint8_t role);
509 
510     /**
511      * @brief Process the indication of disconnection.
512      * @param[in] addr The address of peer device
513      * @param[in] handle The handle of stream
514      * @param[in] role The role of local profile
515      * @since 6.0
516      */
517     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
518 
519     /**
520      * @brief Process the requirement of disconnect.
521      * @param[in] addr The address of peer device
522      * @param[in] role The role of local profile
523      * @since 6.0
524      */
525     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
526 
527     /**
528      * @brief Process the confirm of suspend.
529      * @param[in] msgData The information of message
530      * @param[in] role The role of local profile
531      * @since 6.0
532      */
533     void ProcessSuspendCfm(A2dpAvdtMsgData msgData, uint8_t role);
534 
535      /**
536      * @brief Process the confirm of writting data.
537      * @param[in] msgData The information of message
538      * @param[in] role The role of local profile
539      * @since 6.0
540      */
541     void ProcessWriteCfm(A2dpAvdtMsgData msgData, uint8_t role);
542 
543     /**
544      * @brief Process the confirm of suspend.
545      * @param[in] handle The handle of stream
546      * @param[in] role The role of local profile
547      * @since 6.0
548      */
549     void ProcessSuspendReq(uint16_t handle, uint8_t role);
550 
551     /**
552      * @brief Process the indication of suspend.
553      * @param[in] msgData The information of message
554      * @param[in] role The role of local profile
555      * @since 6.0
556      */
557     void ProcessSuspendInd(A2dpAvdtMsgData msgData, uint8_t role);
558 
559     /**
560      * @brief Set current state
561      *
562      * @since 6.0
563      */
564     void SetStateName(std::string state);
565 
566     /**
567      * @brief Process the indication of delay reporting.
568      * @param[in] msgData The information of message
569      * @param[in] role The role of local profile
570      */
571     void ProcessDelayReportInd(A2dpAvdtMsgData msgData, uint8_t role) const;
572 
573     uint8_t label_ = 0;
574 };
575 
576 class A2dpStateClosing : public utility::StateMachine::State {
577 public:
578     /**
579      * @brief Construct a Closing State object.
580      * @param name State's name.
581      * @param stateMachine State is owned by which StateMachine.
582      * @since 6.0
583      */
A2dpStateClosing(const std::string & name,utility::StateMachine & stateMachine)584     A2dpStateClosing(const std::string &name, utility::StateMachine &stateMachine)
585         : utility::StateMachine::State(name, stateMachine)
586     {}
587 
588     /**
589      * @brief Destruct a Closing object.
590      *
591      * @since 6.0
592      */
593     ~A2dpStateClosing() = default;
594 
595     /**
596      * @brief Operation should be executed when Entry the state.
597      * @since 6.0
598      */
Entry()599     void Entry()
600     {}
601 
602     /**
603      * @brief Operation should be executed when Exit the state.
604      * @since 6.0
605      */
Exit()606     void Exit()
607     {}
608 
609     /**
610      * @brief Dispatch the message of profile peer.
611      * @param[in] The message of profile peer related
612      * @since 6.0
613      */
614     bool Dispatch(const utility::Message &msg);
615 
616 private:
617     /**
618      * @brief Process the indication of disconnection.
619      * @param[in] addr The address of peer device
620      * @param[in] handle The handle of stream
621      * @param[in] role The role of local profile
622      * @since 6.0
623      */
624     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
625 
626     /**
627      * @brief Process the confirm of disconnection.
628      * @param[in] addr The address of peer device
629      * @param[in] handle The handle of stream
630      * @param[in] role The role of local profile
631      * @since 6.0
632      */
633     void ProcessDisconnectCfm(BtAddr addr, uint16_t handle, uint8_t role);
634 
635     /**
636      * @brief Process the indication of close stream.
637      * @param[in] addr The address of peer device
638      * @param[in] handle The handle of stream
639      * @param[in] role The role of local profile
640      * @since 6.0
641      */
642     void ProcessCloseStreamInd(BtAddr addr, uint16_t handle, uint8_t role);
643 
644     /**
645      * @brief Set current state
646      *
647      * @since 6.0
648      */
649     void SetStateName(std::string state);
650 };
651 
652 class A2dpStateMachine : public utility::StateMachine {
653 public:
654     /**
655      * @brief Construct a State machine object.
656      *
657      * @since 6.0
658      */
A2dpStateMachine()659     A2dpStateMachine()
660     {
661         std::unique_ptr<StateMachine::State> idl = std::make_unique<A2dpStateIdle>(A2DP_PROFILE_IDLE, *this);
662         std::unique_ptr<StateMachine::State> configure =
663             std::make_unique<A2dpStateConfigure>(A2DP_PROFILE_CONFIG, *this);
664         std::unique_ptr<StateMachine::State> opening = std::make_unique<A2dpStateOpening>(A2DP_PROFILE_OPENING, *this);
665         std::unique_ptr<StateMachine::State> open = std::make_unique<A2dpStateOpen>(A2DP_PROFILE_OPEN, *this);
666         std::unique_ptr<StateMachine::State> streaming =
667             std::make_unique<A2dpStateStreaming>(A2DP_PROFILE_STREAMING, *this);
668         std::unique_ptr<StateMachine::State> closing = std::make_unique<A2dpStateClosing>(A2DP_PROFILE_CLOSING, *this);
669         Move(idl);
670         Move(configure);
671         Move(opening);
672         Move(open);
673         Move(streaming);
674         Move(closing);
675         InitState(A2DP_PROFILE_IDLE);
676     }
677 
678     /**
679      * @brief Destruct a State machine object.
680      *
681      * @since 6.0
682      */
683     ~A2dpStateMachine() = default;
684 
685     /**
686      * @brief Get the name of state current
687      *
688      * @since 6.0
689      */
690     const std::string GetStateName(void) const;
691 };
692 }  // namespace bluetooth
693 }  // namespace OHOS
694 #endif  // A2DP_STATE_MACHINE_H