1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <array>
21 #include <limits>
22 #include <optional>
23 #include <type_traits>
24 #include <vector>
25 
26 #include "base/functional/callback.h"
27 #include "broadcaster_types.h"
28 #include "bta_le_audio_broadcaster_api.h"
29 #include "main/shim/le_advertising_manager.h"
30 
31 namespace {
32 template <int S, typename StateT = uint8_t>
33 class StateMachine {
34 public:
StateMachine()35   StateMachine() : state_(std::numeric_limits<StateT>::min()) {}
36 
37 protected:
GetState()38   StateT GetState() const { return state_; }
SetState(StateT state)39   void SetState(StateT state) {
40     if (state < S) {
41       state_ = state;
42     }
43   }
44 
45 private:
46   StateT state_;
47 };
48 } /* namespace */
49 
50 /* Broadcast Stream state machine possible states:
51  * Stopped    - No broadcast Audio Stream is being transmitted.
52  * Configuring- Configuration process was started.
53  * Configured - The Broadcast Source has configured its controller for the
54  *              broadcast Audio Stream using implementation-specific
55  *              information or information provided by a higher-layer
56  *              specification. It advertises the information to allow
57  *              Broadcast Sinks and Scan Offloaders to detect the Audio Stream
58  *              and transmits extended advertisements that contain Broadcast
59  *              Audio Announcements, which associate periodic advertising
60  *              trains with broadcast Audio Streams, and transmits periodic
61  *              advertising trains. The periodic advertising trains carry
62  *              Basic Audio Announcements that contain the broadcast Audio
63  *              Stream parameters and metadata. No Audio Data packets are sent
64  *              over the air from the Broadcast Source in this state. The
65  *              periodic advertising trains do not carry the BIGInfo data
66  *              required to synchronize to broadcast Audio Streams.
67  * Enabling   - Controller configuration is in progress (create BIG, setup data path). Target state
68  *              for this intermediate state is Streaming.
69  * Disabling  - Controller deconfiguration is in progress (terminate BIG, remove data path). Target
70  *              state for this intermediate state is Configured.
71  * Stopping   - Broadcast Audio stream and advertisements are being stopped. Target state for this
72  *              intermediate state is Stopped.
73  * Streaming  - The broadcast Audio Stream is enabled on the Broadcast Source,
74  *              allowing audio packets to be transmitted. The Broadcast Source
75  *              transmits extended advertisements that contain Broadcast Audio
76  *              Announcements, which associate periodic advertising trains with
77  *              the broadcast Audio Stream. The Broadcast Source also transmits
78  *              Basic Audio Announcements that contain broadcast Audio Stream
79  *              parameters and metadata and the BIGInfo data required for
80  *              synchronization to the broadcast Audio Stream by using periodic
81  *              advertisements while transmitting the broadcast Audio Stream.
82  *              The Broadcast Source may also transmit control parameters in
83  *              control packets within the broadcast Audio Stream.
84  */
85 namespace bluetooth::le_audio {
86 namespace broadcaster {
87 
88 class IBroadcastStateMachineCallbacks;
89 
90 struct BigConfig {
91   uint8_t status;
92   uint8_t big_id;
93   uint32_t big_sync_delay;
94   uint32_t transport_latency_big;
95   uint8_t phy;
96   uint8_t nse;
97   uint8_t bn;
98   uint8_t pto;
99   uint8_t irc;
100   uint16_t max_pdu;
101   uint16_t iso_interval;
102   std::vector<uint16_t> connection_handles;
103 };
104 
105 struct BroadcastStateMachineConfig {
106   bool is_public;
107   bluetooth::le_audio::BroadcastId broadcast_id;
108   std::string broadcast_name;
109   uint8_t streaming_phy;
110   BroadcastConfiguration config;
111   bluetooth::le_audio::PublicBroadcastAnnouncementData public_announcement;
112   bluetooth::le_audio::BasicAudioAnnouncementData announcement;
113   std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code;
114 };
115 
116 class BroadcastStateMachine : public StateMachine<7> {
117 public:
118   static constexpr uint8_t kAdvSidUndefined = 0xFF;
119   static constexpr uint8_t kPaIntervalMax = 0xA0; /* 160 * 0.625 = 100ms */
120   static constexpr uint8_t kPaIntervalMin = 0x50; /* 80 * 0.625 = 50ms */
121   // LEA broadcast assigned register id, use positive number 0x1
122   // this should not matter since
123   // le_advertising_manager will maintain the reg_id together with client_id
124   // and java/jni is using negative number
125   static constexpr uint8_t kLeAudioBroadcastRegId = 0x1;
126   // Matching the ADDRESS_TYPE_* enums from Java
127   // ADDRESS_TYPE_RANDOM_NON_RESOLVABLE = 2
128   static constexpr int8_t kBroadcastAdvertisingType = 0x2;
129 
130   static void Initialize(IBroadcastStateMachineCallbacks*, AdvertisingCallbacks* adv_callbacks);
131   static std::unique_ptr<BroadcastStateMachine> CreateInstance(BroadcastStateMachineConfig msg);
132 
133   enum class Message : uint8_t {
134     START = 0,
135     SUSPEND,
136     STOP,
137   };
138   static const std::underlying_type<Message>::type MESSAGE_COUNT =
139           static_cast<std::underlying_type<Message>::type>(Message::STOP) + 1;
140 
141   enum class State : uint8_t {
142     STOPPED = 0,
143     CONFIGURING,
144     CONFIGURED,
145     ENABLING,
146     DISABLING,
147     STOPPING,
148     STREAMING,
149   };
150   static const std::underlying_type<State>::type STATE_COUNT =
151           static_cast<std::underlying_type<State>::type>(State::STREAMING) + 1;
152 
GetState(void)153   inline State GetState(void) const { return static_cast<State>(StateMachine::GetState()); }
154 
GetAdvertisingSid()155   virtual uint8_t GetAdvertisingSid() const { return advertising_sid_; }
GetPaInterval()156   virtual uint8_t GetPaInterval() const { return kPaIntervalMax; }
157 
158   virtual bool Initialize() = 0;
159   virtual const std::vector<BroadcastSubgroupCodecConfig>& GetCodecConfig() const = 0;
160   virtual const BroadcastConfiguration& GetBroadcastConfig() const = 0;
161   virtual std::optional<BigConfig> const& GetBigConfig() const = 0;
162   virtual BroadcastStateMachineConfig const& GetStateMachineConfig() const = 0;
163   virtual void RequestOwnAddress(
164           base::Callback<void(uint8_t /* address_type*/, RawAddress /*address*/)> cb) = 0;
165   virtual void RequestOwnAddress() = 0;
166   virtual RawAddress GetOwnAddress() = 0;
167   virtual uint8_t GetOwnAddressType() = 0;
168   virtual std::optional<bluetooth::le_audio::BroadcastCode> GetBroadcastCode() const = 0;
169   virtual bluetooth::le_audio::BroadcastId GetBroadcastId() const = 0;
170   virtual const bluetooth::le_audio::BasicAudioAnnouncementData& GetBroadcastAnnouncement()
171           const = 0;
172   virtual void UpdateBroadcastAnnouncement(
173           bluetooth::le_audio::BasicAudioAnnouncementData announcement) = 0;
174   virtual bool IsPublicBroadcast() = 0;
175   virtual std::string GetBroadcastName() = 0;
176   virtual const bluetooth::le_audio::PublicBroadcastAnnouncementData&
177   GetPublicBroadcastAnnouncement() const = 0;
178   virtual void UpdatePublicBroadcastAnnouncement(
179           uint32_t broadcast_id, const std::string& broadcast_name,
180           const bluetooth::le_audio::PublicBroadcastAnnouncementData& announcement) = 0;
181   virtual void OnCreateAnnouncement(uint8_t advertising_sid, int8_t tx_power, uint8_t status) = 0;
182   virtual void OnEnableAnnouncement(bool enable, uint8_t status) = 0;
183   virtual void OnUpdateAnnouncement(uint8_t status) = 0;
SetMuted(bool muted)184   void SetMuted(bool muted) { is_muted_ = muted; }
IsMuted()185   bool IsMuted() const { return is_muted_; }
186 
187   virtual void HandleHciEvent(uint16_t event, void* data) = 0;
188   virtual void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle) = 0;
189   virtual void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle) = 0;
190 
191   virtual void ProcessMessage(Message event, const void* data = nullptr) = 0;
~BroadcastStateMachine()192   virtual ~BroadcastStateMachine() {}
193 
194 protected:
195   BroadcastStateMachine() = default;
196 
SetState(State state)197   void SetState(State state) {
198     StateMachine::SetState(static_cast<std::underlying_type<State>::type>(state));
199   }
200 
201   uint8_t advertising_sid_ = kAdvSidUndefined;
202   bool is_muted_ = false;
203 
204   RawAddress addr_ = RawAddress::kEmpty;
205   uint8_t addr_type_ = 0;
206 };
207 
208 class IBroadcastStateMachineCallbacks {
209 public:
210   IBroadcastStateMachineCallbacks() = default;
211   virtual ~IBroadcastStateMachineCallbacks() = default;
212   virtual void OnStateMachineCreateStatus(uint32_t broadcast_id, bool initialized) = 0;
213   virtual void OnStateMachineDestroyed(uint32_t broadcast_id) = 0;
214   virtual void OnStateMachineEvent(uint32_t broadcast_id, BroadcastStateMachine::State state,
215                                    const void* data = nullptr) = 0;
216   virtual void OnOwnAddressResponse(uint32_t broadcast_id, uint8_t addr_type,
217                                     RawAddress address) = 0;
218   virtual void OnBigCreated(const std::vector<uint16_t>& conn_handle) = 0;
219   virtual void OnAnnouncementUpdated(uint32_t broadcast_id) = 0;
220 };
221 
222 std::ostream& operator<<(
223         std::ostream& os,
224         const bluetooth::le_audio::broadcaster::BroadcastStateMachine::Message& state);
225 
226 std::ostream& operator<<(
227         std::ostream& os,
228         const bluetooth::le_audio::broadcaster::BroadcastStateMachine::State& state);
229 
230 std::ostream& operator<<(std::ostream& os,
231                          const bluetooth::le_audio::broadcaster::BroadcastStateMachine& machine);
232 
233 std::ostream& operator<<(std::ostream& os,
234                          const bluetooth::le_audio::broadcaster::BigConfig& machine);
235 
236 std::ostream& operator<<(
237         std::ostream& os,
238         const bluetooth::le_audio::broadcaster::BroadcastStateMachineConfig& machine);
239 
240 } /* namespace broadcaster */
241 }  // namespace bluetooth::le_audio
242