1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_bluetooth_sapphire/internal/host/transport/emboss_packet.h"
15
16 #include <pw_bluetooth/hci_android.emb.h>
17 #include <pw_bluetooth/hci_commands.emb.h>
18 #include <pw_bluetooth/hci_test.emb.h>
19
20 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
21 #include "pw_bluetooth_sapphire/internal/host/hci-spec/vendor_protocol.h"
22 #include "pw_bluetooth_sapphire/internal/host/transport/emboss_control_packets.h"
23 #include "pw_unit_test/framework.h"
24
25 namespace bt::hci {
26 namespace {
27
TEST(StaticPacketTest,StaticPacketBasic)28 TEST(StaticPacketTest, StaticPacketBasic) {
29 StaticPacket<pw::bluetooth::emboss::TestCommandPacketWriter> packet;
30 packet.view().header().opcode().BackingStorage().WriteUInt(1234);
31 packet.view().header().parameter_total_size().Write(1);
32 packet.view().payload().Write(13);
33
34 EXPECT_EQ(packet.data(), BufferView({0xD2, 0x04, 0x01, 0x0D}));
35
36 packet.SetToZeros();
37 EXPECT_EQ(packet.data(), BufferView({0, 0, 0, 0}));
38 }
39
TEST(EmbossCommandPacketTest,EmbossCommandPacketBasic)40 TEST(EmbossCommandPacketTest, EmbossCommandPacketBasic) {
41 auto packet =
42 EmbossCommandPacket::New<pw::bluetooth::emboss::TestCommandPacketWriter>(
43 1234);
44 packet.view_t().payload().Write(13);
45
46 EXPECT_EQ(packet.size(), 4u);
47 EXPECT_EQ(packet.data(), BufferView({0xD2, 0x04, 0x01, 0x0D}));
48 EXPECT_EQ(packet.mutable_data(), packet.data());
49 EXPECT_EQ(packet.opcode(), 1234);
50 EXPECT_EQ(packet.ocf(), 1234 & 0x3FF);
51 EXPECT_EQ(packet.ogf(), 1234 >> 10);
52 EXPECT_EQ(packet.view_t().payload().Read(), 13);
53 }
54
TEST(EmbossCommandPacketTest,EmbossCommandPacketDeathTest)55 TEST(EmbossCommandPacketTest, EmbossCommandPacketDeathTest) {
56 EmbossCommandPacket packet =
57 EmbossCommandPacket::New<pw::bluetooth::emboss::TestCommandPacketView>(
58 1234);
59
60 // Try and fail to request view for struct larger than TestCommandPacket.
61 EXPECT_DEATH_IF_SUPPORTED(
62 packet.view<pw::bluetooth::emboss::InquiryCommandView>(),
63 "emboss packet buffer not large enough");
64 // Try and fail to allocate 0 length packet (needs at least 3 bytes for the
65 // header).
66 EXPECT_DEATH_IF_SUPPORTED(
67 EmbossCommandPacket::New<pw::bluetooth::emboss::CommandHeaderView>(1234,
68 0),
69 "command packet size must be at least 3 bytes");
70 }
71
TEST(EmbossEventPacketTest,EmbossEventPacketBasic)72 TEST(EmbossEventPacketTest, EmbossEventPacketBasic) {
73 auto packet =
74 EmbossEventPacket::New<pw::bluetooth::emboss::TestEventPacketWriter>(123);
75 packet.view_t().payload().Write(13);
76
77 EXPECT_EQ(packet.size(), 3u);
78 EXPECT_EQ(packet.data(), BufferView({0x7B, 0x01, 0x0D}));
79 EXPECT_EQ(packet.mutable_data(), packet.data());
80 EXPECT_EQ(packet.event_code(), 123);
81 EXPECT_EQ(packet.view_t().payload().Read(), 13);
82 }
83
TEST(EmbossEventPacketTest,EmbossEventPacketDeathTest)84 TEST(EmbossEventPacketTest, EmbossEventPacketDeathTest) {
85 EmbossEventPacket packet =
86 EmbossEventPacket::New<pw::bluetooth::emboss::TestEventPacketView>(123);
87
88 // Try and fail to allocate 0 length packet (needs at least 2 bytes for the
89 // header).
90 EXPECT_DEATH_IF_SUPPORTED(EmbossEventPacket::New(0),
91 "event packet size must be at least 2 bytes");
92 }
93
TEST(EmbossEventPacketTest,StatusCode)94 TEST(EmbossEventPacketTest, StatusCode) {
95 // Confirm status can be read from vendor subevent.
96 auto packet = EmbossEventPacket::New<
97 pw::bluetooth::vendor::android_hci::LEMultiAdvtStateChangeSubeventWriter>(
98 hci_spec::kVendorDebugEventCode);
99 auto view = packet.view_t();
100 view.status().Write(hci_spec::StatusCode::OPERATION_CANCELLED_BY_HOST);
101 view.vendor_event().subevent_code().Write(
102 hci_spec::vendor::android::kLEMultiAdvtStateChangeSubeventCode);
103
104 ASSERT_TRUE(packet.StatusCode().has_value());
105 EXPECT_EQ(packet.StatusCode().value(),
106 hci_spec::StatusCode::OPERATION_CANCELLED_BY_HOST);
107 EXPECT_EQ(packet.ToResult(),
108 ToResult(hci_spec::StatusCode::OPERATION_CANCELLED_BY_HOST));
109 }
110
111 } // namespace
112 } // namespace bt::hci
113