/* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "hci/hci_layer.h" namespace bluetooth { namespace hci { packet::PacketView GetPacketView( std::unique_ptr packet); std::unique_ptr NextPayload(uint16_t handle); class HciLayerFake : public HciLayer { public: void EnqueueCommand(std::unique_ptr command, common::ContextualOnceCallback on_status) override; void EnqueueCommand( std::unique_ptr command, common::ContextualOnceCallback on_complete) override; void EnqueueCommand(std::unique_ptr command, common::ContextualOnceCallback on_status_or_complete) override; CommandView GetCommand(); CommandView GetCommand(OpCode op_code); void AssertNoQueuedCommand(); void RegisterEventHandler(EventCode event_code, common::ContextualCallback event_handler) override; void UnregisterEventHandler(EventCode event_code) override; void RegisterLeEventHandler( SubeventCode subevent_code, common::ContextualCallback event_handler) override; void UnregisterLeEventHandler(SubeventCode subevent_code) override; void RegisterVendorSpecificEventHandler( VseSubeventCode subevent_code, common::ContextualCallback event_handler) override; void UnregisterVendorSpecificEventHandler(VseSubeventCode subevent_code) override; void IncomingEvent(std::unique_ptr event_builder); void IncomingLeMetaEvent(std::unique_ptr event_builder); void CommandCompleteCallback(EventView event); void CommandStatusCallback(EventView event); void IncomingAclData(uint16_t handle); void IncomingAclData(uint16_t handle, std::unique_ptr acl_builder); void AssertNoOutgoingAclData(); packet::PacketView OutgoingAclData(); common::BidiQueueEnd* GetAclQueueEnd() override; void Disconnect(uint16_t handle, ErrorCode reason) override; protected: void ListDependencies(ModuleList* list) const override; void Start() override; void Stop() override; private: void InitEmptyCommand(); void do_disconnect(uint16_t handle, ErrorCode reason); // Handler-only state. Mutexes are not needed when accessing these fields. std::list> command_complete_callbacks; std::list> command_status_callbacks; std::map> registered_events_; std::map> registered_le_events_; std::map> registered_vs_events_; // thread-safe common::BidiQueue acl_queue_{3 /* TODO: Set queue depth */}; // Most operations must acquire this mutex before manipulating shared state. The ONLY exception // is blocking on a promise, IF your thread is the only one mutating it. Note that SETTING a // promise REQUIRES a lock, since another thread may replace the promise while you are doing so. mutable std::mutex mutex_{}; // Shared state between the test and stack threads std::queue> command_queue_; // We start with Consumed=Set, Command=Unset. // When a command is enqueued, we set Command=set // When a command is popped, we block until Command=Set, then (if the queue is now empty) we // reset Command=Unset and set Consumed=Set. This way we emulate a blocking queue. std::promise command_promise_{}; // Set when at least one command is in the queue std::future command_future_ = command_promise_.get_future(); // GetCommand() blocks until this is fulfilled CommandView empty_command_view_ = CommandView::Create( PacketView(std::make_shared>())); }; } // namespace hci } // namespace bluetooth