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