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 "common/callback.h"
22 #include "os/queue.h"
23 
24 namespace bluetooth {
25 namespace common {
26 
27 //
28 // Interface for one context to send and receive data over
29 // a pair of queues (|BidiQueue|).
30 //
31 template <typename TENQUEUE, typename TDEQUEUE>
32 class BidiQueueEnd : public ::bluetooth::os::IQueueEnqueue<TENQUEUE>,
33                      public ::bluetooth::os::IQueueDequeue<TDEQUEUE> {
34 public:
35   using EnqueueCallback = Callback<std::unique_ptr<TENQUEUE>()>;
36   using DequeueCallback = Callback<void()>;
37 
BidiQueueEnd(::bluetooth::os::IQueueEnqueue<TENQUEUE> * tx,::bluetooth::os::IQueueDequeue<TDEQUEUE> * rx)38   BidiQueueEnd(::bluetooth::os::IQueueEnqueue<TENQUEUE>* tx,
39                ::bluetooth::os::IQueueDequeue<TDEQUEUE>* rx)
40       : tx_(tx), rx_(rx) {}
41 
RegisterEnqueue(::bluetooth::os::Handler * handler,EnqueueCallback callback)42   void RegisterEnqueue(::bluetooth::os::Handler* handler, EnqueueCallback callback) override {
43     tx_->RegisterEnqueue(handler, callback);
44   }
45 
UnregisterEnqueue()46   void UnregisterEnqueue() override { tx_->UnregisterEnqueue(); }
47 
RegisterDequeue(::bluetooth::os::Handler * handler,DequeueCallback callback)48   void RegisterDequeue(::bluetooth::os::Handler* handler, DequeueCallback callback) override {
49     rx_->RegisterDequeue(handler, callback);
50   }
51 
UnregisterDequeue()52   void UnregisterDequeue() override { rx_->UnregisterDequeue(); }
53 
TryDequeue()54   std::unique_ptr<TDEQUEUE> TryDequeue() override { return rx_->TryDequeue(); }
55 
56 private:
57   ::bluetooth::os::IQueueEnqueue<TENQUEUE>* tx_;
58   ::bluetooth::os::IQueueDequeue<TDEQUEUE>* rx_;
59 };
60 
61 //
62 // Interface managing a pair of queues shared between two contexts
63 // (typically layers of the stack).
64 //
65 // The up queue can be used for data to indicate up to bluetooth host and
66 // the down queue can be used for data to sent to bluetooth controller.
67 // Each context uses its |BidiQueueEnd| to manage their data operations:
68 //
69 // The up end:
70 // - Receives data indicated from the down end.
71 // - Sends data to the down end.
72 //
73 // The down end:
74 // - Receives data sent from the up end.
75 // - Indicates data to the up end.
76 //
77 template <typename TUP, typename TDOWN>
78 class BidiQueue {
79 public:
BidiQueue(size_t capacity)80   explicit BidiQueue(size_t capacity)
81       : up_queue_(capacity),
82         down_queue_(capacity),
83         up_end_(&down_queue_, &up_queue_),
84         down_end_(&up_queue_, &down_queue_) {}
85 
GetUpEnd()86   BidiQueueEnd<TDOWN, TUP>* GetUpEnd() { return &up_end_; }
87 
GetDownEnd()88   BidiQueueEnd<TUP, TDOWN>* GetDownEnd() { return &down_end_; }
89 
90 private:
91   ::bluetooth::os::Queue<TUP> up_queue_;
92   ::bluetooth::os::Queue<TDOWN> down_queue_;
93   BidiQueueEnd<TDOWN, TUP> up_end_;
94   BidiQueueEnd<TUP, TDOWN> down_end_;
95 };
96 
97 }  // namespace common
98 }  // namespace bluetooth
99