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