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      * @brief Process the confirm of suspend.
397      * @param[in] msgData The information of message
398      * @param[in] role The role of local profile
399      * @since 6.0
400      */
401     void ProcessSuspendCfm(A2dpAvdtMsgData msgData, uint8_t role);
402     /**
403      * @brief Process the requirement of suspend.
404      * @param[in] handle The handle of stream
405      * @param[in] role The role of local profile
406      * @since 6.0
407      */
408     void ProcessSuspendReq(uint16_t handle, uint8_t role);
409     /**
410      * @brief Process the indication of suspend.
411      * @param[in] msgData The information of message
412      * @param[in] role The role of local profile
413      * @since 6.0
414      */
415     void ProcessSuspendInd(A2dpAvdtMsgData msgData, uint8_t role);
416     /**
417      * @brief Process the indication of close.
418      * @param[in] msgData The information of message
419      * @param[in] role The role of local profile
420      * @since 6.0
421      */
422     void ProcessCloseInd(A2dpAvdtMsgData msgData, uint8_t role);
423 
424     /**
425      * @brief Process the confirm of close.
426      * @param[in] addr The address of peer device
427      * @param[in] role The role of local profile
428      * @since 6.0
429      */
430     void ProcessCloseCfm(BtAddr addr, uint8_t role);
431 
432     /**
433      * @brief Process the confirm of reconfigure.
434      * @param[in] addr The address of peer device
435      * @param[in] role The role of local profile
436      * @param[in] handle The stream handle
437      * @since 6.0
438      */
439     void ProcessReconfigCfm(BtAddr addr, uint8_t role, uint16_t handle);
440 
441     /**
442      * @brief Process the requirement of disconnect.
443      * @param[in] addr The address of peer device
444      * @param[in] role The role of local profile
445      * @since 6.0
446      */
447     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
448 
449     /**
450      * @brief Process the indication of disconnection.
451      * @param[in] addr The address of peer device
452      * @param[in] handle The handle of stream
453      * @param[in] role The role of local profile
454      * @since 6.0
455      */
456     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
457 
458     /**
459      * @brief Process the other cmd of open state.
460      * @param[in] msgData The information of message
461      * @param[in] role The role of local profile
462      * @since 6.0
463      */
464     void ProcessSubOpenState(A2dpAvdtMsgData msgData, uint8_t role, int cmd);
465 
466     /**
467      * @brief Set current state
468      *
469      * @since 6.0
470      */
471     void SetStateName(std::string state);
472 
473     /**
474      * @brief Process the indication of delay reporting.
475      * @param[in] msgData The information of message
476      * @param[in] role The role of local profile
477      */
478     void ProcessDelayReportInd(A2dpAvdtMsgData msgData, uint8_t role) const;
479 
480     uint8_t label_ = 0;
481 };
482 
483 class A2dpStateStreaming : public utility::StateMachine::State {
484 public:
485     /**
486      * @brief Construct a Streaming State object.
487      * @param name State's name.
488      * @param stateMachine State is owned by which StateMachine.
489      * @since 6.0
490      */
A2dpStateStreaming(const std::string &name, utility::StateMachine &stateMachine)491     A2dpStateStreaming(const std::string &name, utility::StateMachine &stateMachine)
492         : utility::StateMachine::State(name, stateMachine)
493     {}
494 
495     /**
496      * @brief Destruct a Streaming object.
497      *
498      * @since 6.0
499      */
500     ~A2dpStateStreaming() = default;
501 
502     /**
503      * @brief Operation should be executed when Entry the state.
504      * @since 6.0
505      */
506     void Entry();
507 
508     /**
509      * @brief Operation should be executed when Exit the state.
510      * @since 6.0
511      */
512     void Exit();
513 
514     /**
515      * @brief Dispatch the message of profile peer.
516      * @param[in] The message of profile peer related
517      * @since 6.0
518      */
519     bool Dispatch(const utility::Message &msg);
520 
521 private:
522     /**
523      * @brief Process the indication of start.
524      * @param[in] msgData The information of message
525      * @param[in] role The role of local profile
526      * @since 6.0
527      */
528     void ProcessStartInd(A2dpAvdtMsgData msgData, uint8_t role);
529     /**
530      * @brief Process the confirm of start.
531      * @param[in] addr The address of peer device
532      * @param[in] role The role of local profile
533      * @since 6.0
534      */
535     void ProcessStartCfm(BtAddr addr, uint8_t role);
536     /**
537      * @brief Process the other cmd of streaming state.
538      * @param[in] msgData The information of message
539      * @param[in] role The role of local profile
540      * @since 6.0
541      */
542     void ProcessSubStreamingState(A2dpAvdtMsgData msgData, uint8_t role, int cmd);
543     /**
544      * @brief Process the confirm of close.
545      * @param[in] addr The address of peer device
546      * @param[in] role The role of local profile
547      * @since 6.0
548      */
549     void ProcessCloseCfm(BtAddr addr, uint8_t role);
550 
551     /**
552      * @brief Process the indication of disconnection.
553      * @param[in] addr The address of peer device
554      * @param[in] handle The handle of stream
555      * @param[in] role The role of local profile
556      * @since 6.0
557      */
558     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
559 
560     /**
561      * @brief Process the requirement of disconnect.
562      * @param[in] addr The address of peer device
563      * @param[in] role The role of local profile
564      * @since 6.0
565      */
566     void ProcessDisconnectReq(BtAddr addr, uint8_t role);
567 
568     /**
569      * @brief Process the confirm of suspend.
570      * @param[in] msgData The information of message
571      * @param[in] role The role of local profile
572      * @since 6.0
573      */
574     void ProcessSuspendCfm(A2dpAvdtMsgData msgData, uint8_t role);
575 
576      /**
577      * @brief Process the confirm of writting data.
578      * @param[in] msgData The information of message
579      * @param[in] role The role of local profile
580      * @since 6.0
581      */
582     void ProcessWriteCfm(A2dpAvdtMsgData msgData, uint8_t role);
583 
584     /**
585      * @brief Process the confirm of suspend.
586      * @param[in] handle The handle of stream
587      * @param[in] role The role of local profile
588      * @since 6.0
589      */
590     void ProcessSuspendReq(uint16_t handle, uint8_t role);
591 
592     /**
593      * @brief Process the indication of suspend.
594      * @param[in] msgData The information of message
595      * @param[in] role The role of local profile
596      * @since 6.0
597      */
598     void ProcessSuspendInd(A2dpAvdtMsgData msgData, uint8_t role);
599 
600     /**
601      * @brief Set current state
602      *
603      * @since 6.0
604      */
605     void SetStateName(std::string state);
606 
607     /**
608      * @brief Process the indication of delay reporting.
609      * @param[in] msgData The information of message
610      * @param[in] role The role of local profile
611      */
612     void ProcessDelayReportInd(A2dpAvdtMsgData msgData, uint8_t role) const;
613 
614     uint8_t label_ = 0;
615 };
616 
617 class A2dpStateClosing : public utility::StateMachine::State {
618 public:
619     /**
620      * @brief Construct a Closing State object.
621      * @param name State's name.
622      * @param stateMachine State is owned by which StateMachine.
623      * @since 6.0
624      */
A2dpStateClosing(const std::string &name, utility::StateMachine &stateMachine)625     A2dpStateClosing(const std::string &name, utility::StateMachine &stateMachine)
626         : utility::StateMachine::State(name, stateMachine)
627     {}
628 
629     /**
630      * @brief Destruct a Closing object.
631      *
632      * @since 6.0
633      */
634     ~A2dpStateClosing() = default;
635 
636     /**
637      * @brief Operation should be executed when Entry the state.
638      * @since 6.0
639      */
Entry()640     void Entry()
641     {}
642 
643     /**
644      * @brief Operation should be executed when Exit the state.
645      * @since 6.0
646      */
Exit()647     void Exit()
648     {}
649 
650     /**
651      * @brief Dispatch the message of profile peer.
652      * @param[in] The message of profile peer related
653      * @since 6.0
654      */
655     bool Dispatch(const utility::Message &msg);
656 
657 private:
658     /**
659      * @brief Process the indication of disconnection.
660      * @param[in] addr The address of peer device
661      * @param[in] handle The handle of stream
662      * @param[in] role The role of local profile
663      * @since 6.0
664      */
665     void ProcessDisconnectInd(BtAddr addr, uint16_t handle, uint8_t role);
666 
667     /**
668      * @brief Process the confirm of disconnection.
669      * @param[in] addr The address of peer device
670      * @param[in] handle The handle of stream
671      * @param[in] role The role of local profile
672      * @since 6.0
673      */
674     void ProcessDisconnectCfm(BtAddr addr, uint16_t handle, uint8_t role);
675 
676     /**
677      * @brief Process the indication of close stream.
678      * @param[in] addr The address of peer device
679      * @param[in] handle The handle of stream
680      * @param[in] role The role of local profile
681      * @since 6.0
682      */
683     void ProcessCloseStreamInd(BtAddr addr, uint16_t handle, uint8_t role);
684 
685     /**
686      * @brief Set current state
687      *
688      * @since 6.0
689      */
690     void SetStateName(std::string state);
691 };
692 
693 class A2dpStateMachine : public utility::StateMachine {
694 public:
695     /**
696      * @brief Construct a State machine object.
697      *
698      * @since 6.0
699      */
A2dpStateMachine()700     A2dpStateMachine()
701     {
702         std::unique_ptr<StateMachine::State> idl = std::make_unique<A2dpStateIdle>(A2DP_PROFILE_IDLE, *this);
703         std::unique_ptr<StateMachine::State> configure =
704             std::make_unique<A2dpStateConfigure>(A2DP_PROFILE_CONFIG, *this);
705         std::unique_ptr<StateMachine::State> opening = std::make_unique<A2dpStateOpening>(A2DP_PROFILE_OPENING, *this);
706         std::unique_ptr<StateMachine::State> open = std::make_unique<A2dpStateOpen>(A2DP_PROFILE_OPEN, *this);
707         std::unique_ptr<StateMachine::State> streaming =
708             std::make_unique<A2dpStateStreaming>(A2DP_PROFILE_STREAMING, *this);
709         std::unique_ptr<StateMachine::State> closing = std::make_unique<A2dpStateClosing>(A2DP_PROFILE_CLOSING, *this);
710         Move(idl);
711         Move(configure);
712         Move(opening);
713         Move(open);
714         Move(streaming);
715         Move(closing);
716         InitState(A2DP_PROFILE_IDLE);
717     }
718 
719     /**
720      * @brief Destruct a State machine object.
721      *
722      * @since 6.0
723      */
724     ~A2dpStateMachine() = default;
725 
726     /**
727      * @brief Get the name of state current
728      *
729      * @since 6.0
730      */
731     const std::string GetStateName(void) const;
732 };
733 }  // namespace bluetooth
734 }  // namespace OHOS
735 #endif  // A2DP_STATE_MACHINE_H