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 25 #include "base/functional/callback.h" 26 #include "broadcaster_types.h" 27 #include "bta_le_audio_broadcaster_api.h" 28 29 namespace { 30 template <int S, typename StateT = uint8_t> 31 class StateMachine { 32 public: StateMachine()33 StateMachine() : state_(std::numeric_limits<StateT>::min()) {} 34 35 protected: GetState()36 StateT GetState() const { return state_; } SetState(StateT state)37 void SetState(StateT state) { 38 if (state < S) state_ = state; 39 } 40 41 private: 42 StateT state_; 43 }; 44 } /* namespace */ 45 46 /* Broadcast Stream state machine possible states: 47 * Stopped - No broadcast Audio Stream is being transmitted. 48 * Configuring- Configuration process was started. 49 * Configured - The Broadcast Source has configured its controller for the 50 * broadcast Audio Stream using implementation-specific 51 * information or information provided by a higher-layer 52 * specification. It advertises the information to allow 53 * Broadcast Sinks and Scan Offloaders to detect the Audio Stream 54 * and transmits extended advertisements that contain Broadcast 55 * Audio Announcements, which associate periodic advertising 56 * trains with broadcast Audio Streams, and transmits periodic 57 * advertising trains. The periodic advertising trains carry 58 * Basic Audio Announcements that contain the broadcast Audio 59 * Stream parameters and metadata. No Audio Data packets are sent 60 * over the air from the Broadcast Source in this state. The 61 * periodic advertising trains do not carry the BIGInfo data 62 * required to synchronize to broadcast Audio Streams. 63 * Stopping - Broadcast Audio stream and advertisements are being stopped. 64 * Streaming - The broadcast Audio Stream is enabled on the Broadcast Source, 65 * allowing audio packets to be transmitted. The Broadcast Source 66 * transmits extended advertisements that contain Broadcast Audio 67 * Announcements, which associate periodic advertising trains with 68 * the broadcast Audio Stream. The Broadcast Source also transmits 69 * Basic Audio Announcements that contain broadcast Audio Stream 70 * parameters and metadata and the BIGInfo data required for 71 * synchronization to the broadcast Audio Stream by using periodic 72 * advertisements while transmitting the broadcast Audio Stream. 73 * The Broadcast Source may also transmit control parameters in 74 * control packets within the broadcast Audio Stream. 75 */ 76 namespace le_audio { 77 namespace broadcaster { 78 79 class IBroadcastStateMachineCallbacks; 80 81 struct BigConfig { 82 uint8_t status; 83 uint8_t big_id; 84 uint32_t big_sync_delay; 85 uint32_t transport_latency_big; 86 uint8_t phy; 87 uint8_t nse; 88 uint8_t bn; 89 uint8_t pto; 90 uint8_t irc; 91 uint16_t max_pdu; 92 uint16_t iso_interval; 93 std::vector<uint16_t> connection_handles; 94 }; 95 96 struct BroadcastStateMachineConfig { 97 bool is_public; 98 bluetooth::le_audio::BroadcastId broadcast_id; 99 std::string broadcast_name; 100 uint8_t streaming_phy; 101 BroadcastCodecWrapper codec_wrapper; 102 BroadcastQosConfig qos_config; 103 bluetooth::le_audio::PublicBroadcastAnnouncementData public_announcement; 104 bluetooth::le_audio::BasicAudioAnnouncementData announcement; 105 std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code; 106 }; 107 108 class BroadcastStateMachine : public StateMachine<5> { 109 public: 110 static constexpr uint8_t kAdvSidUndefined = 0xFF; 111 static constexpr uint8_t kPaIntervalMax = 0xA0; /* 160 * 0.625 = 100ms */ 112 static constexpr uint8_t kPaIntervalMin = 0x50; /* 80 * 0.625 = 50ms */ 113 114 static void Initialize(IBroadcastStateMachineCallbacks*); 115 static std::unique_ptr<BroadcastStateMachine> CreateInstance( 116 BroadcastStateMachineConfig msg); 117 118 enum class Message : uint8_t { 119 START = 0, 120 SUSPEND, 121 STOP, 122 }; 123 static const std::underlying_type<Message>::type MESSAGE_COUNT = 124 static_cast<std::underlying_type<Message>::type>(Message::STOP) + 1; 125 126 enum class State : uint8_t { 127 STOPPED = 0, 128 CONFIGURING, 129 CONFIGURED, 130 STOPPING, 131 STREAMING, 132 }; 133 static const std::underlying_type<State>::type STATE_COUNT = 134 static_cast<std::underlying_type<State>::type>(State::STREAMING) + 1; 135 GetState(void)136 inline State GetState(void) const { 137 return static_cast<State>(StateMachine::GetState()); 138 } 139 GetAdvertisingSid()140 virtual uint8_t GetAdvertisingSid() const { return advertising_sid_; } GetPaInterval()141 virtual uint8_t GetPaInterval() const { return kPaIntervalMax; } 142 143 virtual bool Initialize() = 0; 144 virtual const BroadcastCodecWrapper& GetCodecConfig() const = 0; 145 virtual std::optional<BigConfig> const& GetBigConfig() const = 0; 146 virtual BroadcastStateMachineConfig const& GetStateMachineConfig() const = 0; 147 virtual void RequestOwnAddress( 148 base::Callback<void(uint8_t /* address_type*/, RawAddress /*address*/)> 149 cb) = 0; 150 virtual void RequestOwnAddress() = 0; 151 virtual RawAddress GetOwnAddress() = 0; 152 virtual uint8_t GetOwnAddressType() = 0; 153 virtual std::optional<bluetooth::le_audio::BroadcastCode> GetBroadcastCode() 154 const = 0; 155 virtual bluetooth::le_audio::BroadcastId GetBroadcastId() const = 0; 156 virtual const bluetooth::le_audio::BasicAudioAnnouncementData& 157 GetBroadcastAnnouncement() const = 0; 158 virtual void UpdateBroadcastAnnouncement( 159 bluetooth::le_audio::BasicAudioAnnouncementData announcement) = 0; 160 virtual bool IsPublicBroadcast() = 0; 161 virtual std::string GetBroadcastName() = 0; 162 virtual const bluetooth::le_audio::PublicBroadcastAnnouncementData& 163 GetPublicBroadcastAnnouncement() const = 0; 164 virtual void UpdatePublicBroadcastAnnouncement( 165 uint32_t broadcast_id, const std::string& broadcast_name, 166 const bluetooth::le_audio::PublicBroadcastAnnouncementData& 167 announcement) = 0; SetMuted(bool muted)168 void SetMuted(bool muted) { is_muted_ = muted; }; IsMuted()169 bool IsMuted() const { return is_muted_; }; 170 171 virtual void HandleHciEvent(uint16_t event, void* data) = 0; 172 virtual void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle) = 0; 173 virtual void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle) = 0; 174 175 virtual void ProcessMessage(Message event, const void* data = nullptr) = 0; ~BroadcastStateMachine()176 virtual ~BroadcastStateMachine() {} 177 178 protected: 179 BroadcastStateMachine() = default; 180 SetState(State state)181 void SetState(State state) { 182 StateMachine::SetState( 183 static_cast<std::underlying_type<State>::type>(state)); 184 } 185 186 uint8_t advertising_sid_ = kAdvSidUndefined; 187 bool is_muted_ = false; 188 189 RawAddress addr_ = RawAddress::kEmpty; 190 uint8_t addr_type_ = 0; 191 }; 192 193 class IBroadcastStateMachineCallbacks { 194 public: 195 IBroadcastStateMachineCallbacks() = default; 196 virtual ~IBroadcastStateMachineCallbacks() = default; 197 virtual void OnStateMachineCreateStatus(uint32_t broadcast_id, 198 bool initialized) = 0; 199 virtual void OnStateMachineDestroyed(uint32_t broadcast_id) = 0; 200 virtual void OnStateMachineEvent(uint32_t broadcast_id, 201 BroadcastStateMachine::State state, 202 const void* data = nullptr) = 0; 203 virtual void OnOwnAddressResponse(uint32_t broadcast_id, uint8_t addr_type, 204 RawAddress address) = 0; 205 virtual void OnBigCreated(const std::vector<uint16_t>& conn_handle) = 0; 206 }; 207 208 std::ostream& operator<<( 209 std::ostream& os, 210 const le_audio::broadcaster::BroadcastStateMachine::Message& state); 211 212 std::ostream& operator<<( 213 std::ostream& os, 214 const le_audio::broadcaster::BroadcastStateMachine::State& state); 215 216 std::ostream& operator<<( 217 std::ostream& os, 218 const le_audio::broadcaster::BroadcastStateMachine& machine); 219 220 std::ostream& operator<<(std::ostream& os, 221 const le_audio::broadcaster::BigConfig& machine); 222 223 std::ostream& operator<<( 224 std::ostream& os, 225 const le_audio::broadcaster::BroadcastStateMachineConfig& machine); 226 227 } /* namespace broadcaster */ 228 } /* namespace le_audio */ 229