blob: 92c6a1f109f24308faa82a0d4a9bc4a19e851b1e [file] [log] [blame]
/******************************************************************************
*
* 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 <memory>
#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 <class A, class B, std::unique_ptr<B> (*A_TO_B)(std::unique_ptr<A>)>
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<B, A> queue_a_{10};
common::BidiQueue<B, A> queue_b_{10};
os::EnqueueBuffer<B> down_buffer_a_{queue_a_.GetDownEnd()};
os::EnqueueBuffer<B> 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<A, B>* GetQueueAUpEnd() {
return queue_a_.GetUpEnd();
}
/* This methd returns the UpEnd of queue B */
common::BidiQueueEnd<A, B>* GetQueueBUpEnd() {
return queue_b_.GetUpEnd();
}
};
namespace {
std::unique_ptr<packet::PacketView<packet::kLittleEndian>> BuilderToView(
std::unique_ptr<packet::BasePacketBuilder> up_thing) {
auto bytes = std::make_shared<std::vector<uint8_t>>();
bluetooth::packet::BitInserter i(*bytes);
bytes->reserve(up_thing->size());
up_thing->Serialize(i);
return std::make_unique<packet::PacketView<packet::kLittleEndian>>(bytes);
}
} // namespace
using WiredPairOfL2capQueues =
WiredPairOfBiDiQueues<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>, BuilderToView>;
} // namespace testing
} // namespace common
} // namespace bluetooth