• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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