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 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include <memory>
23 
24 #include "hci/le_security_interface.h"
25 #include "packet/raw_builder.h"
26 #include "security/pairing_handler_le.h"
27 #include "security/test/mocks.h"
28 
29 #include "os/handler.h"
30 #include "os/queue.h"
31 #include "os/thread.h"
32 
33 using namespace std::chrono_literals;
34 using testing::_;
35 using testing::Invoke;
36 using testing::InvokeWithoutArgs;
37 using testing::Matcher;
38 using testing::SaveArg;
39 
40 using bluetooth::hci::CommandCompleteView;
41 using bluetooth::hci::CommandStatusView;
42 using bluetooth::hci::EncryptionChangeBuilder;
43 using bluetooth::hci::EncryptionEnabled;
44 using bluetooth::hci::ErrorCode;
45 using bluetooth::hci::EventBuilder;
46 using bluetooth::hci::EventView;
47 using bluetooth::hci::LeSecurityCommandBuilder;
48 
49 namespace bluetooth {
50 namespace security {
51 
52 namespace {
53 
54 template <class T>
GetPacketView(std::unique_ptr<T> packet)55 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<T> packet) {
56   auto bytes = std::make_shared<std::vector<uint8_t>>();
57   BitInserter i(*bytes);
58   bytes->reserve(packet->size());
59   packet->Serialize(i);
60   return packet::PacketView<packet::kLittleEndian>(bytes);
61 }
62 
sync_handler(os::Handler * handler)63 void sync_handler(os::Handler* handler) {
64   std::promise<void> promise;
65   auto future = promise.get_future();
66   handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
67   auto status = future.wait_for(std::chrono::milliseconds(3));
68   EXPECT_EQ(status, std::future_status::ready);
69 }
70 }  // namespace
71 
72 class FakeL2capTest : public testing::Test {
73  protected:
SetUp()74   void SetUp() {}
75 
TearDown()76   void TearDown() {}
77 
78  public:
79 };
80 
my_enqueue_callback()81 void my_enqueue_callback() {
82   LOG_INFO("packet ready for dequeue!");
83 }
84 
85 /* This test verifies that Just Works pairing flow works.
86  * Both simulated devices specify capabilities as NO_INPUT_NO_OUTPUT, and secure connecitons support */
TEST_F(FakeL2capTest,test_bidi_queue_example)87 TEST_F(FakeL2capTest, test_bidi_queue_example) {
88   os::Thread* thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
89   os::Handler* handler_ = new os::Handler(thread_);
90 
91   common::BidiQueue<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>> bidi_queue{10};
92 
93   os::EnqueueBuffer<packet::BasePacketBuilder> enqueue_buffer{bidi_queue.GetDownEnd()};
94 
95   // This is test packet we are sending down the queue to the other end;
96   auto test_packet = EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, 0x0020, EncryptionEnabled::ON);
97 
98   // send the packet through the queue
99   enqueue_buffer.Enqueue(std::move(test_packet), handler_);
100 
101   // give queue some time to push the packet through
102   sync_handler(handler_);
103 
104   // packet is through the queue, receive it on the other end.
105   auto test_packet_from_other_end = bidi_queue.GetUpEnd()->TryDequeue();
106 
107   EXPECT_TRUE(test_packet_from_other_end != nullptr);
108 
109   // This is how we receive data
110   os::EnqueueBuffer<packet::PacketView<packet::kLittleEndian>> up_end_enqueue_buffer{bidi_queue.GetUpEnd()};
111   bidi_queue.GetDownEnd()->RegisterDequeue(handler_, common::Bind(&my_enqueue_callback));
112 
113   auto packet_one = std::make_unique<packet::RawBuilder>();
114   packet_one->AddOctets({1, 2, 3});
115 
116   up_end_enqueue_buffer.Enqueue(std::make_unique<PacketView<kLittleEndian>>(GetPacketView(std::move(packet_one))),
117                                 handler_);
118 
119   sync_handler(handler_);
120 
121   auto other_end_packet = bidi_queue.GetDownEnd()->TryDequeue();
122   EXPECT_TRUE(other_end_packet != nullptr);
123 
124   bidi_queue.GetDownEnd()->UnregisterDequeue();
125   handler_->Clear();
126   delete handler_;
127   delete thread_;
128 }
129 
130 }  // namespace security
131 }  // namespace bluetooth