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/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 bluetooth::le_audio::BroadcastId broadcast_id; 98 uint8_t streaming_phy; 99 BroadcastCodecWrapper codec_wrapper; 100 BroadcastQosConfig qos_config; 101 bluetooth::le_audio::BasicAudioAnnouncementData announcement; 102 std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code; 103 }; 104 105 class BroadcastStateMachine : public StateMachine<5> { 106 public: 107 static constexpr uint8_t kAdvSidUndefined = 0xFF; 108 static constexpr uint8_t kPaIntervalMax = 0xA0; /* 160 * 0.625 = 100ms */ 109 static constexpr uint8_t kPaIntervalMin = 0x50; /* 80 * 0.625 = 50ms */ 110 111 static void Initialize(IBroadcastStateMachineCallbacks*); 112 static std::unique_ptr<BroadcastStateMachine> CreateInstance( 113 BroadcastStateMachineConfig msg); 114 115 enum class Message : uint8_t { 116 START = 0, 117 SUSPEND, 118 STOP, 119 }; 120 static const std::underlying_type<Message>::type MESSAGE_COUNT = 121 static_cast<std::underlying_type<Message>::type>(Message::STOP) + 1; 122 123 enum class State : uint8_t { 124 STOPPED = 0, 125 CONFIGURING, 126 CONFIGURED, 127 STOPPING, 128 STREAMING, 129 }; 130 static const std::underlying_type<State>::type STATE_COUNT = 131 static_cast<std::underlying_type<State>::type>(State::STREAMING) + 1; 132 GetState(void)133 inline State GetState(void) const { 134 return static_cast<State>(StateMachine::GetState()); 135 } 136 GetAdvertisingSid()137 virtual uint8_t GetAdvertisingSid() const { return advertising_sid_; } GetPaInterval()138 virtual uint8_t GetPaInterval() const { return kPaIntervalMax; } 139 140 virtual bool Initialize() = 0; 141 virtual const BroadcastCodecWrapper& GetCodecConfig() const = 0; 142 virtual std::optional<BigConfig> const& GetBigConfig() const = 0; 143 virtual BroadcastStateMachineConfig const& GetStateMachineConfig() const = 0; 144 virtual void RequestOwnAddress( 145 base::Callback<void(uint8_t /* address_type*/, RawAddress /*address*/)> 146 cb) = 0; 147 virtual void RequestOwnAddress() = 0; 148 virtual RawAddress GetOwnAddress() = 0; 149 virtual uint8_t GetOwnAddressType() = 0; 150 virtual std::optional<bluetooth::le_audio::BroadcastCode> GetBroadcastCode() 151 const = 0; 152 virtual bluetooth::le_audio::BroadcastId GetBroadcastId() const = 0; 153 virtual const bluetooth::le_audio::BasicAudioAnnouncementData& 154 GetBroadcastAnnouncement() const = 0; 155 virtual void UpdateBroadcastAnnouncement( 156 bluetooth::le_audio::BasicAudioAnnouncementData announcement) = 0; SetMuted(bool muted)157 void SetMuted(bool muted) { is_muted_ = muted; }; IsMuted()158 bool IsMuted() const { return is_muted_; }; 159 160 virtual void HandleHciEvent(uint16_t event, void* data) = 0; 161 virtual void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle) = 0; 162 virtual void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle) = 0; 163 164 virtual void ProcessMessage(Message event, const void* data = nullptr) = 0; ~BroadcastStateMachine()165 virtual ~BroadcastStateMachine() {} 166 167 protected: 168 BroadcastStateMachine() = default; 169 SetState(State state)170 void SetState(State state) { 171 StateMachine::SetState( 172 static_cast<std::underlying_type<State>::type>(state)); 173 } 174 175 uint8_t advertising_sid_ = kAdvSidUndefined; 176 bool is_muted_ = false; 177 178 RawAddress addr_ = RawAddress::kEmpty; 179 uint8_t addr_type_ = 0; 180 }; 181 182 class IBroadcastStateMachineCallbacks { 183 public: 184 IBroadcastStateMachineCallbacks() = default; 185 virtual ~IBroadcastStateMachineCallbacks() = default; 186 virtual void OnStateMachineCreateStatus(uint32_t broadcast_id, 187 bool initialized) = 0; 188 virtual void OnStateMachineDestroyed(uint32_t broadcast_id) = 0; 189 virtual void OnStateMachineEvent(uint32_t broadcast_id, 190 BroadcastStateMachine::State state, 191 const void* data = nullptr) = 0; 192 virtual void OnOwnAddressResponse(uint32_t broadcast_id, uint8_t addr_type, 193 RawAddress address) = 0; 194 virtual void OnBigCreated(const std::vector<uint16_t>& conn_handle) = 0; 195 }; 196 197 std::ostream& operator<<( 198 std::ostream& os, 199 const le_audio::broadcaster::BroadcastStateMachine::Message& state); 200 201 std::ostream& operator<<( 202 std::ostream& os, 203 const le_audio::broadcaster::BroadcastStateMachine::State& state); 204 205 std::ostream& operator<<( 206 std::ostream& os, 207 const le_audio::broadcaster::BroadcastStateMachine& machine); 208 209 std::ostream& operator<<(std::ostream& os, 210 const le_audio::broadcaster::BigConfig& machine); 211 212 std::ostream& operator<<( 213 std::ostream& os, 214 const le_audio::broadcaster::BroadcastStateMachineConfig& machine); 215 216 } /* namespace broadcaster */ 217 } /* namespace le_audio */ 218