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) state_ = state;
41   }
42 
43  private:
44   StateT state_;
45 };
46 } /* namespace */
47 
48 /* Broadcast Stream state machine possible states:
49  * Stopped    - No broadcast Audio Stream is being transmitted.
50  * Configuring- Configuration process was started.
51  * Configured - The Broadcast Source has configured its controller for the
52  *              broadcast Audio Stream using implementation-specific
53  *              information or information provided by a higher-layer
54  *              specification. It advertises the information to allow
55  *              Broadcast Sinks and Scan Offloaders to detect the Audio Stream
56  *              and transmits extended advertisements that contain Broadcast
57  *              Audio Announcements, which associate periodic advertising
58  *              trains with broadcast Audio Streams, and transmits periodic
59  *              advertising trains. The periodic advertising trains carry
60  *              Basic Audio Announcements that contain the broadcast Audio
61  *              Stream parameters and metadata. No Audio Data packets are sent
62  *              over the air from the Broadcast Source in this state. The
63  *              periodic advertising trains do not carry the BIGInfo data
64  *              required to synchronize to broadcast Audio Streams.
65  * Stopping   - Broadcast Audio stream and advertisements are being stopped.
66  * Streaming  - The broadcast Audio Stream is enabled on the Broadcast Source,
67  *              allowing audio packets to be transmitted. The Broadcast Source
68  *              transmits extended advertisements that contain Broadcast Audio
69  *              Announcements, which associate periodic advertising trains with
70  *              the broadcast Audio Stream. The Broadcast Source also transmits
71  *              Basic Audio Announcements that contain broadcast Audio Stream
72  *              parameters and metadata and the BIGInfo data required for
73  *              synchronization to the broadcast Audio Stream by using periodic
74  *              advertisements while transmitting the broadcast Audio Stream.
75  *              The Broadcast Source may also transmit control parameters in
76  *              control packets within the broadcast Audio Stream.
77  */
78 namespace bluetooth::le_audio {
79 namespace broadcaster {
80 
81 class IBroadcastStateMachineCallbacks;
82 
83 struct BigConfig {
84   uint8_t status;
85   uint8_t big_id;
86   uint32_t big_sync_delay;
87   uint32_t transport_latency_big;
88   uint8_t phy;
89   uint8_t nse;
90   uint8_t bn;
91   uint8_t pto;
92   uint8_t irc;
93   uint16_t max_pdu;
94   uint16_t iso_interval;
95   std::vector<uint16_t> connection_handles;
96 };
97 
98 struct BroadcastStateMachineConfig {
99   bool is_public;
100   bluetooth::le_audio::BroadcastId broadcast_id;
101   std::string broadcast_name;
102   uint8_t streaming_phy;
103   BroadcastConfiguration config;
104   bluetooth::le_audio::PublicBroadcastAnnouncementData public_announcement;
105   bluetooth::le_audio::BasicAudioAnnouncementData announcement;
106   std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code;
107 };
108 
109 class BroadcastStateMachine : public StateMachine<5> {
110  public:
111   static constexpr uint8_t kAdvSidUndefined = 0xFF;
112   static constexpr uint8_t kPaIntervalMax = 0xA0; /* 160 * 0.625 = 100ms */
113   static constexpr uint8_t kPaIntervalMin = 0x50; /* 80 * 0.625 = 50ms */
114   // LEA broadcast assigned register id, use positive number 0x1
115   // this should not matter since
116   // le_advertising_manager will maintain the reg_id together with client_id
117   // and java/jni is using negative number
118   static constexpr uint8_t kLeAudioBroadcastRegId = 0x1;
119   // Matching the ADDRESS_TYPE_* enums from Java
120   // ADDRESS_TYPE_RANDOM_NON_RESOLVABLE = 2
121   static constexpr int8_t kBroadcastAdvertisingType = 0x2;
122 
123   static void Initialize(IBroadcastStateMachineCallbacks*,
124                          AdvertisingCallbacks* adv_callbacks);
125   static std::unique_ptr<BroadcastStateMachine> CreateInstance(
126       BroadcastStateMachineConfig msg);
127 
128   enum class Message : uint8_t {
129     START = 0,
130     SUSPEND,
131     STOP,
132   };
133   static const std::underlying_type<Message>::type MESSAGE_COUNT =
134       static_cast<std::underlying_type<Message>::type>(Message::STOP) + 1;
135 
136   enum class State : uint8_t {
137     STOPPED = 0,
138     CONFIGURING,
139     CONFIGURED,
140     STOPPING,
141     STREAMING,
142   };
143   static const std::underlying_type<State>::type STATE_COUNT =
144       static_cast<std::underlying_type<State>::type>(State::STREAMING) + 1;
145 
GetState(void)146   inline State GetState(void) const {
147     return static_cast<State>(StateMachine::GetState());
148   }
149 
GetAdvertisingSid()150   virtual uint8_t GetAdvertisingSid() const { return advertising_sid_; }
GetPaInterval()151   virtual uint8_t GetPaInterval() const { return kPaIntervalMax; }
152 
153   virtual bool Initialize() = 0;
154   virtual const std::vector<BroadcastSubgroupCodecConfig>& GetCodecConfig()
155       const = 0;
156   virtual const BroadcastConfiguration& GetBroadcastConfig() const = 0;
157   virtual std::optional<BigConfig> const& GetBigConfig() const = 0;
158   virtual BroadcastStateMachineConfig const& GetStateMachineConfig() const = 0;
159   virtual void RequestOwnAddress(
160       base::Callback<void(uint8_t /* address_type*/, RawAddress /*address*/)>
161           cb) = 0;
162   virtual void RequestOwnAddress() = 0;
163   virtual RawAddress GetOwnAddress() = 0;
164   virtual uint8_t GetOwnAddressType() = 0;
165   virtual std::optional<bluetooth::le_audio::BroadcastCode> GetBroadcastCode()
166       const = 0;
167   virtual bluetooth::le_audio::BroadcastId GetBroadcastId() const = 0;
168   virtual const bluetooth::le_audio::BasicAudioAnnouncementData&
169   GetBroadcastAnnouncement() const = 0;
170   virtual void UpdateBroadcastAnnouncement(
171       bluetooth::le_audio::BasicAudioAnnouncementData announcement) = 0;
172   virtual bool IsPublicBroadcast() = 0;
173   virtual std::string GetBroadcastName() = 0;
174   virtual const bluetooth::le_audio::PublicBroadcastAnnouncementData&
175   GetPublicBroadcastAnnouncement() const = 0;
176   virtual void UpdatePublicBroadcastAnnouncement(
177       uint32_t broadcast_id, const std::string& broadcast_name,
178       const bluetooth::le_audio::PublicBroadcastAnnouncementData&
179           announcement) = 0;
180   virtual void OnCreateAnnouncement(uint8_t advertising_sid, int8_t tx_power,
181                                     uint8_t status) = 0;
182   virtual void OnEnableAnnouncement(bool enable, uint8_t status) = 0;
SetMuted(bool muted)183   void SetMuted(bool muted) { is_muted_ = muted; };
IsMuted()184   bool IsMuted() const { return is_muted_; };
185 
186   virtual void HandleHciEvent(uint16_t event, void* data) = 0;
187   virtual void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle) = 0;
188   virtual void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle) = 0;
189 
190   virtual void ProcessMessage(Message event, const void* data = nullptr) = 0;
~BroadcastStateMachine()191   virtual ~BroadcastStateMachine() {}
192 
193  protected:
194   BroadcastStateMachine() = default;
195 
SetState(State state)196   void SetState(State state) {
197     StateMachine::SetState(
198         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,
213                                           bool initialized) = 0;
214   virtual void OnStateMachineDestroyed(uint32_t broadcast_id) = 0;
215   virtual void OnStateMachineEvent(uint32_t broadcast_id,
216                                    BroadcastStateMachine::State state,
217                                    const void* data = nullptr) = 0;
218   virtual void OnOwnAddressResponse(uint32_t broadcast_id, uint8_t addr_type,
219                                     RawAddress address) = 0;
220   virtual void OnBigCreated(const std::vector<uint16_t>& conn_handle) = 0;
221 };
222 
223 std::ostream& operator<<(
224     std::ostream& os,
225     const bluetooth::le_audio::broadcaster::BroadcastStateMachine::Message&
226         state);
227 
228 std::ostream& operator<<(
229     std::ostream& os,
230     const bluetooth::le_audio::broadcaster::BroadcastStateMachine::State&
231         state);
232 
233 std::ostream& operator<<(
234     std::ostream& os,
235     const bluetooth::le_audio::broadcaster::BroadcastStateMachine& machine);
236 
237 std::ostream& operator<<(
238     std::ostream& os,
239     const bluetooth::le_audio::broadcaster::BigConfig& machine);
240 
241 std::ostream& operator<<(
242     std::ostream& os,
243     const bluetooth::le_audio::broadcaster::BroadcastStateMachineConfig&
244         machine);
245 
246 } /* namespace broadcaster */
247 }  // namespace bluetooth::le_audio
248