/****************************************************************************** * * Copyright 2019 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. * ******************************************************************************/ #pragma once #include #include "common/bidi_queue.h" #include "os/handler.h" #include "packet/base_packet_builder.h" #include "packet/bit_inserter.h" #include "packet/packet_view.h" namespace bluetooth { namespace common { namespace testing { /* This class is a pair of BiDiQueues, that have down ends "wired" together. It can be used i.e. to mock L2cap * interface, and provide two queues, where each sends packets of type A, and receives packets of type B */ template (*A_TO_B)(std::unique_ptr)> class WiredPairOfBiDiQueues { void dequeue_callback_a() { auto down_thing = queue_a_.GetDownEnd()->TryDequeue(); if (!down_thing) LOG_ERROR("Received dequeue, but no data ready..."); down_buffer_b_.Enqueue(A_TO_B(std::move(down_thing)), handler_); } void dequeue_callback_b() { auto down_thing = queue_b_.GetDownEnd()->TryDequeue(); if (!down_thing) LOG_ERROR("Received dequeue, but no data ready..."); down_buffer_a_.Enqueue(A_TO_B(std::move(down_thing)), handler_); } os::Handler* handler_; common::BidiQueue queue_a_{10}; common::BidiQueue queue_b_{10}; os::EnqueueBuffer down_buffer_a_{queue_a_.GetDownEnd()}; os::EnqueueBuffer down_buffer_b_{queue_b_.GetDownEnd()}; public: WiredPairOfBiDiQueues(os::Handler* handler) : handler_(handler) { queue_a_.GetDownEnd()->RegisterDequeue( handler_, common::Bind(&WiredPairOfBiDiQueues::dequeue_callback_a, common::Unretained(this))); queue_b_.GetDownEnd()->RegisterDequeue( handler_, common::Bind(&WiredPairOfBiDiQueues::dequeue_callback_b, common::Unretained(this))); } ~WiredPairOfBiDiQueues() { queue_a_.GetDownEnd()->UnregisterDequeue(); queue_b_.GetDownEnd()->UnregisterDequeue(); } /* This methd returns the UpEnd of queue A */ common::BidiQueueEnd* GetQueueAUpEnd() { return queue_a_.GetUpEnd(); } /* This methd returns the UpEnd of queue B */ common::BidiQueueEnd* GetQueueBUpEnd() { return queue_b_.GetUpEnd(); } }; namespace { std::unique_ptr> BuilderToView( std::unique_ptr up_thing) { auto bytes = std::make_shared>(); bluetooth::packet::BitInserter i(*bytes); bytes->reserve(up_thing->size()); up_thing->Serialize(i); return std::make_unique>(bytes); } } // namespace using WiredPairOfL2capQueues = WiredPairOfBiDiQueues, BuilderToView>; } // namespace testing } // namespace common } // namespace bluetooth