1 /******************************************************************************
2 *
3 * Copyright 2019 The Android Open Source Project
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
19 #pragma once
20
21 #include <memory>
22
23 #include "common/bidi_queue.h"
24 #include "os/handler.h"
25 #include "packet/base_packet_builder.h"
26 #include "packet/bit_inserter.h"
27 #include "packet/packet_view.h"
28
29 namespace bluetooth {
30 namespace common {
31 namespace testing {
32
33 /* This class is a pair of BiDiQueues, that have down ends "wired" together. It can be used i.e. to mock L2cap
34 * interface, and provide two queues, where each sends packets of type A, and receives packets of type B */
35 template <class A, class B, std::unique_ptr<B> (*A_TO_B)(std::unique_ptr<A>)>
36 class WiredPairOfBiDiQueues {
dequeue_callback_a()37 void dequeue_callback_a() {
38 auto down_thing = queue_a_.GetDownEnd()->TryDequeue();
39 if (!down_thing) LOG_ERROR("Received dequeue, but no data ready...");
40
41 down_buffer_b_.Enqueue(A_TO_B(std::move(down_thing)), handler_);
42 }
43
dequeue_callback_b()44 void dequeue_callback_b() {
45 auto down_thing = queue_b_.GetDownEnd()->TryDequeue();
46 if (!down_thing) LOG_ERROR("Received dequeue, but no data ready...");
47
48 down_buffer_a_.Enqueue(A_TO_B(std::move(down_thing)), handler_);
49 }
50
51 os::Handler* handler_;
52 common::BidiQueue<B, A> queue_a_{10};
53 common::BidiQueue<B, A> queue_b_{10};
54 os::EnqueueBuffer<B> down_buffer_a_{queue_a_.GetDownEnd()};
55 os::EnqueueBuffer<B> down_buffer_b_{queue_b_.GetDownEnd()};
56
57 public:
WiredPairOfBiDiQueues(os::Handler * handler)58 WiredPairOfBiDiQueues(os::Handler* handler) : handler_(handler) {
59 queue_a_.GetDownEnd()->RegisterDequeue(
60 handler_, common::Bind(&WiredPairOfBiDiQueues::dequeue_callback_a, common::Unretained(this)));
61 queue_b_.GetDownEnd()->RegisterDequeue(
62 handler_, common::Bind(&WiredPairOfBiDiQueues::dequeue_callback_b, common::Unretained(this)));
63 }
64
~WiredPairOfBiDiQueues()65 ~WiredPairOfBiDiQueues() {
66 queue_a_.GetDownEnd()->UnregisterDequeue();
67 queue_b_.GetDownEnd()->UnregisterDequeue();
68 }
69
70 /* This methd returns the UpEnd of queue A */
GetQueueAUpEnd()71 common::BidiQueueEnd<A, B>* GetQueueAUpEnd() {
72 return queue_a_.GetUpEnd();
73 }
74
75 /* This methd returns the UpEnd of queue B */
GetQueueBUpEnd()76 common::BidiQueueEnd<A, B>* GetQueueBUpEnd() {
77 return queue_b_.GetUpEnd();
78 }
79 };
80
81 namespace {
BuilderToView(std::unique_ptr<packet::BasePacketBuilder> up_thing)82 std::unique_ptr<packet::PacketView<packet::kLittleEndian>> BuilderToView(
83 std::unique_ptr<packet::BasePacketBuilder> up_thing) {
84 auto bytes = std::make_shared<std::vector<uint8_t>>();
85 bluetooth::packet::BitInserter i(*bytes);
86 bytes->reserve(up_thing->size());
87 up_thing->Serialize(i);
88 return std::make_unique<packet::PacketView<packet::kLittleEndian>>(bytes);
89 }
90 } // namespace
91
92 using WiredPairOfL2capQueues =
93 WiredPairOfBiDiQueues<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>, BuilderToView>;
94
95 } // namespace testing
96 } // namespace common
97 } // namespace bluetooth
98