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