1*61c4878aSAndroid Build Coastguard Worker // Copyright 2023 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker #include <numeric>
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include "lib/stdcompat/utility.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h" // IWYU pragma: keep
19*61c4878aSAndroid Build Coastguard Worker
20*61c4878aSAndroid Build Coastguard Worker // clang-format off
21*61c4878aSAndroid Build Coastguard Worker // All emboss headers are listed (even if they don't have explicit tests) to
22*61c4878aSAndroid Build Coastguard Worker // ensure they are compiled.
23*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/att.emb.h" // IWYU pragma: keep
24*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_commands.emb.h" // IWYU pragma: keep
25*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_common.emb.h"
26*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_data.emb.h"
27*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_events.emb.h" // IWYU pragma: keep
28*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_h4.emb.h" // IWYU pragma: keep
29*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_test.emb.h"
30*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/hci_android.emb.h" // IWYU pragma: keep
31*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/l2cap_frames.emb.h" // IWYU pragma: keep
32*61c4878aSAndroid Build Coastguard Worker #include "pw_bluetooth/rfcomm_frames.emb.h" // IWYU pragma: keep
33*61c4878aSAndroid Build Coastguard Worker // clang-format on
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard Worker namespace pw::bluetooth {
36*61c4878aSAndroid Build Coastguard Worker namespace {
37*61c4878aSAndroid Build Coastguard Worker
38*61c4878aSAndroid Build Coastguard Worker // Examples are used in docs.rst.
TEST(EmbossExamples,MakeView)39*61c4878aSAndroid Build Coastguard Worker TEST(EmbossExamples, MakeView) {
40*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_bluetooth-examples-make_view]
41*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 4> buffer = {0x00, 0x01, 0x02, 0x03};
42*61c4878aSAndroid Build Coastguard Worker auto view = emboss::MakeTestCommandPacketView(&buffer);
43*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(view.IsComplete());
44*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.payload().Read(), 0x03);
45*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_bluetooth-examples-make_view]
46*61c4878aSAndroid Build Coastguard Worker }
47*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,MakeView)48*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, MakeView) {
49*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 4> buffer = {0x00, 0x01, 0x02, 0x03};
50*61c4878aSAndroid Build Coastguard Worker auto view = emboss::MakeTestCommandPacketView(&buffer);
51*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(view.IsComplete());
52*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.payload().Read(), 0x03);
53*61c4878aSAndroid Build Coastguard Worker }
54*61c4878aSAndroid Build Coastguard Worker
InitializeIsoPacket(const emboss::IsoDataFramePacketWriter & view,emboss::TsFlag ts_flag,emboss::IsoDataPbFlag pb_flag,size_t sdu_fragment_size)55*61c4878aSAndroid Build Coastguard Worker static void InitializeIsoPacket(const emboss::IsoDataFramePacketWriter& view,
56*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag ts_flag,
57*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag pb_flag,
58*61c4878aSAndroid Build Coastguard Worker size_t sdu_fragment_size) {
59*61c4878aSAndroid Build Coastguard Worker view.header().connection_handle().Write(0x123);
60*61c4878aSAndroid Build Coastguard Worker view.header().ts_flag().Write(ts_flag);
61*61c4878aSAndroid Build Coastguard Worker view.header().pb_flag().Write(pb_flag);
62*61c4878aSAndroid Build Coastguard Worker
63*61c4878aSAndroid Build Coastguard Worker size_t optional_fields_total_size = 0;
64*61c4878aSAndroid Build Coastguard Worker if (ts_flag == emboss::TsFlag::TIMESTAMP_PRESENT) {
65*61c4878aSAndroid Build Coastguard Worker optional_fields_total_size += 4;
66*61c4878aSAndroid Build Coastguard Worker }
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard Worker if ((pb_flag == emboss::IsoDataPbFlag::FIRST_FRAGMENT) ||
69*61c4878aSAndroid Build Coastguard Worker (pb_flag == emboss::IsoDataPbFlag::COMPLETE_SDU)) {
70*61c4878aSAndroid Build Coastguard Worker optional_fields_total_size += 4;
71*61c4878aSAndroid Build Coastguard Worker }
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard Worker view.header().data_total_length().Write(sdu_fragment_size +
74*61c4878aSAndroid Build Coastguard Worker optional_fields_total_size);
75*61c4878aSAndroid Build Coastguard Worker }
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker // This definition has a mix of full-width values and bitfields and includes
78*61c4878aSAndroid Build Coastguard Worker // conditional bitfields. Let's add this to verify that the structure itself
79*61c4878aSAndroid Build Coastguard Worker // doesn't get changed incorrectly and that emboss' size calculation matches
80*61c4878aSAndroid Build Coastguard Worker // ours.
TEST(EmbossTest,CheckIsoPacketSize)81*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, CheckIsoPacketSize) {
82*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 2048> buffer;
83*61c4878aSAndroid Build Coastguard Worker const size_t kSduFragmentSize = 100;
84*61c4878aSAndroid Build Coastguard Worker auto view = emboss::MakeIsoDataFramePacketView(&buffer);
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
87*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_NOT_PRESENT,
88*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::FIRST_FRAGMENT,
89*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
90*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
91*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
92*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize + 4);
93*61c4878aSAndroid Build Coastguard Worker
94*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
95*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_NOT_PRESENT,
96*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::INTERMEDIATE_FRAGMENT,
97*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
98*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
99*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
100*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize);
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
103*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_NOT_PRESENT,
104*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::COMPLETE_SDU,
105*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
106*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
107*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
108*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize + 4);
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
111*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_NOT_PRESENT,
112*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::LAST_FRAGMENT,
113*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
114*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
115*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
116*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize);
117*61c4878aSAndroid Build Coastguard Worker
118*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
119*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_PRESENT,
120*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::FIRST_FRAGMENT,
121*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
122*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
123*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
124*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize + 8);
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
127*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_PRESENT,
128*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::INTERMEDIATE_FRAGMENT,
129*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
130*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
131*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
132*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize + 4);
133*61c4878aSAndroid Build Coastguard Worker
134*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
135*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_PRESENT,
136*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::COMPLETE_SDU,
137*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
138*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
139*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
140*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize + 8);
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard Worker InitializeIsoPacket(view,
143*61c4878aSAndroid Build Coastguard Worker emboss::TsFlag::TIMESTAMP_PRESENT,
144*61c4878aSAndroid Build Coastguard Worker emboss::IsoDataPbFlag::LAST_FRAGMENT,
145*61c4878aSAndroid Build Coastguard Worker kSduFragmentSize);
146*61c4878aSAndroid Build Coastguard Worker ASSERT_TRUE(view.IntrinsicSizeInBytes().Ok());
147*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(view.IntrinsicSizeInBytes().Read()),
148*61c4878aSAndroid Build Coastguard Worker view.hdr_size().Read() + kSduFragmentSize + 4);
149*61c4878aSAndroid Build Coastguard Worker }
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker // Test and demonstrate various ways of reading opcodes.
TEST(EmbossTest,ReadOpcodesFromCommandHeader)152*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadOpcodesFromCommandHeader) {
153*61c4878aSAndroid Build Coastguard Worker // First two bytes will be used as opcode.
154*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 4> buffer = {0x00, 0x00, 0x02, 0x03};
155*61c4878aSAndroid Build Coastguard Worker auto view = emboss::MakeTestCommandPacketView(&buffer);
156*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(view.IsComplete());
157*61c4878aSAndroid Build Coastguard Worker auto header = view.header();
158*61c4878aSAndroid Build Coastguard Worker
159*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_enum().Read(), emboss::OpCode::UNSPECIFIED);
160*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().BackingStorage().ReadUInt(), 0x0000);
161*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_bits().ogf().Read(), 0x00);
162*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_bits().ocf().Read(), 0x00);
163*61c4878aSAndroid Build Coastguard Worker // TODO: https://pwbug.dev/338068316 - Delete these opcode type
164*61c4878aSAndroid Build Coastguard Worker // OpCodeBits cases once opcode has type OpCode.
165*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().ogf().Read(), 0x00);
166*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().ocf().Read(), 0x00);
167*61c4878aSAndroid Build Coastguard Worker
168*61c4878aSAndroid Build Coastguard Worker // LINK_KEY_REQUEST_REPLY is OGF 0x01 and OCF 0x0B.
169*61c4878aSAndroid Build Coastguard Worker header.opcode_enum().Write(emboss::OpCode::LINK_KEY_REQUEST_REPLY);
170*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_enum().Read(),
171*61c4878aSAndroid Build Coastguard Worker emboss::OpCode::LINK_KEY_REQUEST_REPLY);
172*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().BackingStorage().ReadUInt(), 0x040B);
173*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_bits().ogf().Read(), 0x01);
174*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_bits().ocf().Read(), 0x0B);
175*61c4878aSAndroid Build Coastguard Worker // TODO: https://pwbug.dev/338068316 - Delete these opcode type
176*61c4878aSAndroid Build Coastguard Worker // OpCodeBits cases once opcode has type OpCode.
177*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().ogf().Read(), 0x01);
178*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().ocf().Read(), 0x0B);
179*61c4878aSAndroid Build Coastguard Worker }
180*61c4878aSAndroid Build Coastguard Worker
181*61c4878aSAndroid Build Coastguard Worker // Test and demonstrate various ways of writing opcodes.
TEST(EmbossTest,WriteOpcodesFromCommandHeader)182*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, WriteOpcodesFromCommandHeader) {
183*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 4> buffer = {};
184*61c4878aSAndroid Build Coastguard Worker buffer.fill(0xFF);
185*61c4878aSAndroid Build Coastguard Worker auto view = emboss::MakeTestCommandPacketView(&buffer);
186*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(view.IsComplete());
187*61c4878aSAndroid Build Coastguard Worker auto header = view.header();
188*61c4878aSAndroid Build Coastguard Worker
189*61c4878aSAndroid Build Coastguard Worker header.opcode_enum().Write(emboss::OpCode::UNSPECIFIED);
190*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().BackingStorage().ReadUInt(), 0x0000);
191*61c4878aSAndroid Build Coastguard Worker
192*61c4878aSAndroid Build Coastguard Worker header.opcode().ocf().Write(0x0B);
193*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().BackingStorage().ReadUInt(), 0x000B);
194*61c4878aSAndroid Build Coastguard Worker
195*61c4878aSAndroid Build Coastguard Worker header.opcode().ogf().Write(0x01);
196*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode().BackingStorage().ReadUInt(), 0x040B);
197*61c4878aSAndroid Build Coastguard Worker // LINK_KEY_REQUEST_REPLY is OGF 0x01 and OCF 0x0B.
198*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.opcode_enum().Read(),
199*61c4878aSAndroid Build Coastguard Worker emboss::OpCode::LINK_KEY_REQUEST_REPLY);
200*61c4878aSAndroid Build Coastguard Worker }
201*61c4878aSAndroid Build Coastguard Worker
202*61c4878aSAndroid Build Coastguard Worker // Test and demonstrate using to_underlying with OpCodes enums
TEST(EmbossTest,OPCodeEnumsWithToUnderlying)203*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, OPCodeEnumsWithToUnderlying) {
204*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x0000, cpp23::to_underlying(emboss::OpCode::UNSPECIFIED));
205*61c4878aSAndroid Build Coastguard Worker }
206*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadAndWriteOpcodesInCommandResponseHeader)207*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadAndWriteOpcodesInCommandResponseHeader) {
208*61c4878aSAndroid Build Coastguard Worker // First two bytes will be used as opcode.
209*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t,
210*61c4878aSAndroid Build Coastguard Worker emboss::ReadBufferSizeCommandCompleteEventView::SizeInBytes()>
211*61c4878aSAndroid Build Coastguard Worker buffer;
212*61c4878aSAndroid Build Coastguard Worker std::iota(buffer.begin(), buffer.end(), 100);
213*61c4878aSAndroid Build Coastguard Worker auto view = emboss::MakeReadBufferSizeCommandCompleteEventView(&buffer);
214*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(view.IsComplete());
215*61c4878aSAndroid Build Coastguard Worker auto header = view.command_complete();
216*61c4878aSAndroid Build Coastguard Worker
217*61c4878aSAndroid Build Coastguard Worker header.command_opcode().BackingStorage().WriteUInt(0x0000);
218*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode_enum().Read(), emboss::OpCode::UNSPECIFIED);
219*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode().BackingStorage().ReadUInt(), 0x0000);
220*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode_bits().ogf().Read(), 0x00);
221*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode_bits().ocf().Read(), 0x00);
222*61c4878aSAndroid Build Coastguard Worker // TODO: https://pwbug.dev/338068316 - Delete these command_opcode type
223*61c4878aSAndroid Build Coastguard Worker // OpCodeBits cases once command_opcode has type OpCode.
224*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode().ogf().Read(), 0x00);
225*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode().ocf().Read(), 0x00);
226*61c4878aSAndroid Build Coastguard Worker
227*61c4878aSAndroid Build Coastguard Worker // LINK_KEY_REQUEST_REPLY is OGF 0x01 and OCF 0x0B.
228*61c4878aSAndroid Build Coastguard Worker header.command_opcode_enum().Write(emboss::OpCode::LINK_KEY_REQUEST_REPLY);
229*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode_enum().Read(),
230*61c4878aSAndroid Build Coastguard Worker emboss::OpCode::LINK_KEY_REQUEST_REPLY);
231*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode().BackingStorage().ReadUInt(), 0x040B);
232*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode_bits().ogf().Read(), 0x01);
233*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode_bits().ocf().Read(), 0x0B);
234*61c4878aSAndroid Build Coastguard Worker // TODO: https://pwbug.dev/338068316 - Delete these command_opcode type
235*61c4878aSAndroid Build Coastguard Worker // OpCodeBits cases once command_opcode has type OpCode.
236*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode().ogf().Read(), 0x01);
237*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.command_opcode().ocf().Read(), 0x0B);
238*61c4878aSAndroid Build Coastguard Worker }
239*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadAndWriteEventCodesInEventHeader)240*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadAndWriteEventCodesInEventHeader) {
241*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, emboss::EventHeaderWriter::SizeInBytes()> buffer;
242*61c4878aSAndroid Build Coastguard Worker std::iota(buffer.begin(), buffer.end(), 100);
243*61c4878aSAndroid Build Coastguard Worker auto header = emboss::MakeEventHeaderView(&buffer);
244*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(header.IsComplete());
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard Worker header.event_code_uint().Write(
247*61c4878aSAndroid Build Coastguard Worker cpp23::to_underlying(emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS));
248*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.event_code_enum().Read(),
249*61c4878aSAndroid Build Coastguard Worker emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS);
250*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
251*61c4878aSAndroid Build Coastguard Worker header.event_code_uint().Read(),
252*61c4878aSAndroid Build Coastguard Worker cpp23::to_underlying(emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS));
253*61c4878aSAndroid Build Coastguard Worker
254*61c4878aSAndroid Build Coastguard Worker // TODO: https://pwbug.dev/338068316 - Delete these event_code type
255*61c4878aSAndroid Build Coastguard Worker // UInt cases once event_code has type EventCode.
256*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(
257*61c4878aSAndroid Build Coastguard Worker header.event_code().Read(),
258*61c4878aSAndroid Build Coastguard Worker cpp23::to_underlying(emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS));
259*61c4878aSAndroid Build Coastguard Worker
260*61c4878aSAndroid Build Coastguard Worker header.event_code().Write(
261*61c4878aSAndroid Build Coastguard Worker cpp23::to_underlying(emboss::EventCode::CONNECTION_REQUEST));
262*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(header.event_code_uint().Read(),
263*61c4878aSAndroid Build Coastguard Worker cpp23::to_underlying(emboss::EventCode::CONNECTION_REQUEST));
264*61c4878aSAndroid Build Coastguard Worker }
265*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadCommandPayloadLength)266*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadCommandPayloadLength) {
267*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 8> hci_buffer = {
268*61c4878aSAndroid Build Coastguard Worker 0x4c, 0xfc, 0x05, 0x73, 0x86, 0x30, 0x00, 0x00};
269*61c4878aSAndroid Build Coastguard Worker emboss::CommandHeaderView command = emboss::MakeCommandHeaderView(
270*61c4878aSAndroid Build Coastguard Worker hci_buffer.data(), emboss::CommandHeaderView::SizeInBytes());
271*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(command.IsComplete());
272*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(command.parameter_total_size().Read(), 5);
273*61c4878aSAndroid Build Coastguard Worker }
274*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadEventPayloadLength)275*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadEventPayloadLength) {
276*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 8> hci_buffer = {0x0e, 0x04, 0x01, 0x2e, 0xfc, 0x00};
277*61c4878aSAndroid Build Coastguard Worker emboss::EventHeaderView event = emboss::MakeEventHeaderView(
278*61c4878aSAndroid Build Coastguard Worker hci_buffer.data(), emboss::EventHeaderView::SizeInBytes());
279*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(event.IsComplete());
280*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(event.parameter_total_size().Read(), 4);
281*61c4878aSAndroid Build Coastguard Worker }
282*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadAclPayloadLength)283*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadAclPayloadLength) {
284*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 16> hci_buffer = {0x0c,
285*61c4878aSAndroid Build Coastguard Worker 0x00,
286*61c4878aSAndroid Build Coastguard Worker 0x0c,
287*61c4878aSAndroid Build Coastguard Worker 0x00,
288*61c4878aSAndroid Build Coastguard Worker 0x08,
289*61c4878aSAndroid Build Coastguard Worker 0x00,
290*61c4878aSAndroid Build Coastguard Worker 0x01,
291*61c4878aSAndroid Build Coastguard Worker 0x00,
292*61c4878aSAndroid Build Coastguard Worker 0x06,
293*61c4878aSAndroid Build Coastguard Worker 0x06,
294*61c4878aSAndroid Build Coastguard Worker 0x04,
295*61c4878aSAndroid Build Coastguard Worker 0x00,
296*61c4878aSAndroid Build Coastguard Worker 0x5b,
297*61c4878aSAndroid Build Coastguard Worker 0x00,
298*61c4878aSAndroid Build Coastguard Worker 0x41,
299*61c4878aSAndroid Build Coastguard Worker 0x00};
300*61c4878aSAndroid Build Coastguard Worker emboss::AclDataFrameHeaderView acl = emboss::MakeAclDataFrameHeaderView(
301*61c4878aSAndroid Build Coastguard Worker hci_buffer.data(), emboss::AclDataFrameHeaderView::SizeInBytes());
302*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(acl.IsComplete());
303*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(acl.data_total_length().Read(), 12);
304*61c4878aSAndroid Build Coastguard Worker }
305*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadScoPayloadLength)306*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadScoPayloadLength) {
307*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, 9> hci_buffer = {
308*61c4878aSAndroid Build Coastguard Worker 0x02, 0x00, 0x06, 0xFF, 0xD3, 0x4A, 0x1B, 0x2C, 0x3D};
309*61c4878aSAndroid Build Coastguard Worker emboss::ScoDataHeaderView sco = emboss::ScoDataHeaderView(
310*61c4878aSAndroid Build Coastguard Worker hci_buffer.data(), emboss::ScoDataHeaderView::SizeInBytes());
311*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(sco.IsComplete());
312*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(sco.data_total_length().Read(), 6);
313*61c4878aSAndroid Build Coastguard Worker }
314*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,WriteSniffMode)315*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, WriteSniffMode) {
316*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, emboss::SniffModeCommandWriter::SizeInBytes()> buffer{};
317*61c4878aSAndroid Build Coastguard Worker emboss::SniffModeCommandWriter writer =
318*61c4878aSAndroid Build Coastguard Worker emboss::MakeSniffModeCommandView(&buffer);
319*61c4878aSAndroid Build Coastguard Worker writer.header().opcode_enum().Write(emboss::OpCode::SNIFF_MODE);
320*61c4878aSAndroid Build Coastguard Worker writer.header().parameter_total_size().Write(
321*61c4878aSAndroid Build Coastguard Worker emboss::SniffModeCommandWriter::SizeInBytes() -
322*61c4878aSAndroid Build Coastguard Worker emboss::CommandHeaderWriter::SizeInBytes());
323*61c4878aSAndroid Build Coastguard Worker writer.connection_handle().Write(0x0004);
324*61c4878aSAndroid Build Coastguard Worker writer.sniff_max_interval().Write(0x0330);
325*61c4878aSAndroid Build Coastguard Worker writer.sniff_min_interval().Write(0x0190);
326*61c4878aSAndroid Build Coastguard Worker writer.sniff_attempt().Write(0x0004);
327*61c4878aSAndroid Build Coastguard Worker writer.sniff_timeout().Write(0x0001);
328*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, emboss::SniffModeCommandView::SizeInBytes()> expected{
329*61c4878aSAndroid Build Coastguard Worker // Opcode (LSB, MSB)
330*61c4878aSAndroid Build Coastguard Worker 0x03,
331*61c4878aSAndroid Build Coastguard Worker 0x08,
332*61c4878aSAndroid Build Coastguard Worker // Parameter Total Size
333*61c4878aSAndroid Build Coastguard Worker 0x0A,
334*61c4878aSAndroid Build Coastguard Worker // Connection Handle (LSB, MSB)
335*61c4878aSAndroid Build Coastguard Worker 0x04,
336*61c4878aSAndroid Build Coastguard Worker 0x00,
337*61c4878aSAndroid Build Coastguard Worker // Sniff Max Interval (LSB, MSB)
338*61c4878aSAndroid Build Coastguard Worker 0x30,
339*61c4878aSAndroid Build Coastguard Worker 0x03,
340*61c4878aSAndroid Build Coastguard Worker // Sniff Min Interval (LSB, MSB)
341*61c4878aSAndroid Build Coastguard Worker 0x90,
342*61c4878aSAndroid Build Coastguard Worker 0x01,
343*61c4878aSAndroid Build Coastguard Worker // Sniff Attempt (LSB, MSB)
344*61c4878aSAndroid Build Coastguard Worker 0x04,
345*61c4878aSAndroid Build Coastguard Worker 0x00,
346*61c4878aSAndroid Build Coastguard Worker // Sniff Timeout (LSB, MSB)
347*61c4878aSAndroid Build Coastguard Worker 0x01,
348*61c4878aSAndroid Build Coastguard Worker 0x00};
349*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(buffer, expected);
350*61c4878aSAndroid Build Coastguard Worker }
351*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadSniffMode)352*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadSniffMode) {
353*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, emboss::SniffModeCommandView::SizeInBytes()> buffer{
354*61c4878aSAndroid Build Coastguard Worker // Opcode (LSB, MSB)
355*61c4878aSAndroid Build Coastguard Worker 0x03,
356*61c4878aSAndroid Build Coastguard Worker 0x08,
357*61c4878aSAndroid Build Coastguard Worker // Parameter Total Size
358*61c4878aSAndroid Build Coastguard Worker 0x0A,
359*61c4878aSAndroid Build Coastguard Worker // Connection Handle (LSB, MSB)
360*61c4878aSAndroid Build Coastguard Worker 0x04,
361*61c4878aSAndroid Build Coastguard Worker 0x00,
362*61c4878aSAndroid Build Coastguard Worker // Sniff Max Interval (LSB, MSB)
363*61c4878aSAndroid Build Coastguard Worker 0x30,
364*61c4878aSAndroid Build Coastguard Worker 0x03,
365*61c4878aSAndroid Build Coastguard Worker // Sniff Min Interval (LSB, MSB)
366*61c4878aSAndroid Build Coastguard Worker 0x90,
367*61c4878aSAndroid Build Coastguard Worker 0x01,
368*61c4878aSAndroid Build Coastguard Worker // Sniff Attempt (LSB, MSB)
369*61c4878aSAndroid Build Coastguard Worker 0x04,
370*61c4878aSAndroid Build Coastguard Worker 0x00,
371*61c4878aSAndroid Build Coastguard Worker // Sniff Timeout (LSB, MSB)
372*61c4878aSAndroid Build Coastguard Worker 0x01,
373*61c4878aSAndroid Build Coastguard Worker 0x00};
374*61c4878aSAndroid Build Coastguard Worker emboss::SniffModeCommandView view = emboss::MakeSniffModeCommandView(&buffer);
375*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.header().opcode_enum().Read(), emboss::OpCode::SNIFF_MODE);
376*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(view.header().IsComplete());
377*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.connection_handle().Read(), 0x0004);
378*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.sniff_max_interval().Read(), 0x0330);
379*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.sniff_min_interval().Read(), 0x0190);
380*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.sniff_attempt().Read(), 0x0004);
381*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(view.sniff_timeout().Read(), 0x0001);
382*61c4878aSAndroid Build Coastguard Worker }
383*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadRfcomm)384*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadRfcomm) {
385*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t,
386*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrame::MinSizeInBytes() + /*credits*/ 1 +
387*61c4878aSAndroid Build Coastguard Worker /*payload*/ 3>
388*61c4878aSAndroid Build Coastguard Worker buffer_with_credits = {// Address
389*61c4878aSAndroid Build Coastguard Worker 0x19,
390*61c4878aSAndroid Build Coastguard Worker // UIH Poll/Final
391*61c4878aSAndroid Build Coastguard Worker 0xFF,
392*61c4878aSAndroid Build Coastguard Worker // Information Length
393*61c4878aSAndroid Build Coastguard Worker 0x07,
394*61c4878aSAndroid Build Coastguard Worker // Credits
395*61c4878aSAndroid Build Coastguard Worker 0x0A,
396*61c4878aSAndroid Build Coastguard Worker // Payload/Information
397*61c4878aSAndroid Build Coastguard Worker 0xAB,
398*61c4878aSAndroid Build Coastguard Worker 0xCD,
399*61c4878aSAndroid Build Coastguard Worker 0xEF,
400*61c4878aSAndroid Build Coastguard Worker // FCS
401*61c4878aSAndroid Build Coastguard Worker 0x49};
402*61c4878aSAndroid Build Coastguard Worker
403*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrameView rfcomm =
404*61c4878aSAndroid Build Coastguard Worker emboss::MakeRfcommFrameView(&buffer_with_credits);
405*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.Ok());
406*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.credits().Read(), 10);
407*61c4878aSAndroid Build Coastguard Worker
408*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[0].Read(), 0xAB);
409*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[1].Read(), 0xCD);
410*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[2].Read(), 0xEF);
411*61c4878aSAndroid Build Coastguard Worker
412*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.fcs().Read(), 0x49);
413*61c4878aSAndroid Build Coastguard Worker
414*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t,
415*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrame::MinSizeInBytes() +
416*61c4878aSAndroid Build Coastguard Worker /*payload*/ 3>
417*61c4878aSAndroid Build Coastguard Worker buffer_without_credits = {// Address
418*61c4878aSAndroid Build Coastguard Worker 0x19,
419*61c4878aSAndroid Build Coastguard Worker // UIH
420*61c4878aSAndroid Build Coastguard Worker 0xEF,
421*61c4878aSAndroid Build Coastguard Worker // Information Length
422*61c4878aSAndroid Build Coastguard Worker 0x07,
423*61c4878aSAndroid Build Coastguard Worker // Payload/Information
424*61c4878aSAndroid Build Coastguard Worker 0xAB,
425*61c4878aSAndroid Build Coastguard Worker 0xCD,
426*61c4878aSAndroid Build Coastguard Worker 0xEF,
427*61c4878aSAndroid Build Coastguard Worker // FCS
428*61c4878aSAndroid Build Coastguard Worker 0x55};
429*61c4878aSAndroid Build Coastguard Worker
430*61c4878aSAndroid Build Coastguard Worker rfcomm = emboss::MakeRfcommFrameView(&buffer_without_credits);
431*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.Ok());
432*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(rfcomm.has_credits().ValueOrDefault());
433*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[0].Read(), 0xAB);
434*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[1].Read(), 0xCD);
435*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[2].Read(), 0xEF);
436*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.fcs().Read(), 0x55);
437*61c4878aSAndroid Build Coastguard Worker }
438*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,ReadRfcommExtended)439*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, ReadRfcommExtended) {
440*61c4878aSAndroid Build Coastguard Worker constexpr size_t kMaxShortLength = 0x7f;
441*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t,
442*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrame::MinSizeInBytes() + /*length_extended*/ 1 +
443*61c4878aSAndroid Build Coastguard Worker /*credits*/ 1 +
444*61c4878aSAndroid Build Coastguard Worker /*payload*/ (kMaxShortLength + 1)>
445*61c4878aSAndroid Build Coastguard Worker buffer_extended_length_with_credits = {
446*61c4878aSAndroid Build Coastguard Worker // Address
447*61c4878aSAndroid Build Coastguard Worker 0x19,
448*61c4878aSAndroid Build Coastguard Worker // UIH Poll/Final
449*61c4878aSAndroid Build Coastguard Worker 0xFF,
450*61c4878aSAndroid Build Coastguard Worker // Information Length
451*61c4878aSAndroid Build Coastguard Worker 0x00,
452*61c4878aSAndroid Build Coastguard Worker 0x01,
453*61c4878aSAndroid Build Coastguard Worker // Credits
454*61c4878aSAndroid Build Coastguard Worker 0x0A,
455*61c4878aSAndroid Build Coastguard Worker // Payload/Information
456*61c4878aSAndroid Build Coastguard Worker 0xAB,
457*61c4878aSAndroid Build Coastguard Worker 0xCD,
458*61c4878aSAndroid Build Coastguard Worker 0xEF,
459*61c4878aSAndroid Build Coastguard Worker };
460*61c4878aSAndroid Build Coastguard Worker
461*61c4878aSAndroid Build Coastguard Worker // FCS
462*61c4878aSAndroid Build Coastguard Worker buffer_extended_length_with_credits
463*61c4878aSAndroid Build Coastguard Worker [buffer_extended_length_with_credits.size() - 1] = 0x49;
464*61c4878aSAndroid Build Coastguard Worker
465*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrameView rfcomm =
466*61c4878aSAndroid Build Coastguard Worker emboss::MakeRfcommFrameView(&buffer_extended_length_with_credits);
467*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.Ok());
468*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.has_credits().ValueOrDefault());
469*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.has_length_extended().ValueOrDefault());
470*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information_length().Read(), 128);
471*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[0].Read(), 0xAB);
472*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[1].Read(), 0xCD);
473*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.information()[2].Read(), 0xEF);
474*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(rfcomm.fcs().Read(), 0x49);
475*61c4878aSAndroid Build Coastguard Worker }
476*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,WriteRfcomm)477*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, WriteRfcomm) {
478*61c4878aSAndroid Build Coastguard Worker const std::array<uint8_t, 3> expected_payload = {0xAB, 0xCD, 0xEF};
479*61c4878aSAndroid Build Coastguard Worker constexpr size_t kFrameSize = emboss::RfcommFrame::MinSizeInBytes() +
480*61c4878aSAndroid Build Coastguard Worker /*credits*/ 1 + expected_payload.size();
481*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, kFrameSize> buffer{};
482*61c4878aSAndroid Build Coastguard Worker
483*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrameWriter rfcomm = emboss::MakeRfcommFrameView(&buffer);
484*61c4878aSAndroid Build Coastguard Worker rfcomm.extended_address().Write(true);
485*61c4878aSAndroid Build Coastguard Worker rfcomm.command_response_direction().Write(
486*61c4878aSAndroid Build Coastguard Worker emboss::RfcommCommandResponseAndDirection::COMMAND_FROM_RESPONDER);
487*61c4878aSAndroid Build Coastguard Worker rfcomm.channel().Write(3);
488*61c4878aSAndroid Build Coastguard Worker rfcomm.control().Write(
489*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrameType::
490*61c4878aSAndroid Build Coastguard Worker UNNUMBERED_INFORMATION_WITH_HEADER_CHECK_AND_POLL_FINAL);
491*61c4878aSAndroid Build Coastguard Worker
492*61c4878aSAndroid Build Coastguard Worker rfcomm.length_extended_flag().Write(emboss::RfcommLengthExtended::NORMAL);
493*61c4878aSAndroid Build Coastguard Worker rfcomm.length().Write(expected_payload.size());
494*61c4878aSAndroid Build Coastguard Worker
495*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.has_credits().ValueOrDefault());
496*61c4878aSAndroid Build Coastguard Worker rfcomm.credits().Write(10);
497*61c4878aSAndroid Build Coastguard Worker
498*61c4878aSAndroid Build Coastguard Worker std::memcpy(rfcomm.information().BackingStorage().data(),
499*61c4878aSAndroid Build Coastguard Worker expected_payload.data(),
500*61c4878aSAndroid Build Coastguard Worker expected_payload.size());
501*61c4878aSAndroid Build Coastguard Worker rfcomm.fcs().Write(0x49);
502*61c4878aSAndroid Build Coastguard Worker
503*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, kFrameSize> expected{// Address
504*61c4878aSAndroid Build Coastguard Worker 0x19,
505*61c4878aSAndroid Build Coastguard Worker // UIH Poll/Final
506*61c4878aSAndroid Build Coastguard Worker 0xFF,
507*61c4878aSAndroid Build Coastguard Worker // Information Length
508*61c4878aSAndroid Build Coastguard Worker 0x07,
509*61c4878aSAndroid Build Coastguard Worker // Credits
510*61c4878aSAndroid Build Coastguard Worker 0x0A,
511*61c4878aSAndroid Build Coastguard Worker // Payload/Information
512*61c4878aSAndroid Build Coastguard Worker 0xAB,
513*61c4878aSAndroid Build Coastguard Worker 0xCD,
514*61c4878aSAndroid Build Coastguard Worker 0xEF,
515*61c4878aSAndroid Build Coastguard Worker // FCS
516*61c4878aSAndroid Build Coastguard Worker 0x49};
517*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(buffer, expected);
518*61c4878aSAndroid Build Coastguard Worker }
519*61c4878aSAndroid Build Coastguard Worker
TEST(EmbossTest,WriteRfcommExtended)520*61c4878aSAndroid Build Coastguard Worker TEST(EmbossTest, WriteRfcommExtended) {
521*61c4878aSAndroid Build Coastguard Worker const std::array<uint8_t, 128> expected_payload = {0xAB, 0xCD, 0xEF};
522*61c4878aSAndroid Build Coastguard Worker constexpr size_t kFrameSize = emboss::RfcommFrame::MinSizeInBytes() +
523*61c4878aSAndroid Build Coastguard Worker /* length_extended */ 1 +
524*61c4878aSAndroid Build Coastguard Worker /*credits*/ 1 + expected_payload.size();
525*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, kFrameSize> buffer{};
526*61c4878aSAndroid Build Coastguard Worker
527*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrameWriter rfcomm = emboss::MakeRfcommFrameView(&buffer);
528*61c4878aSAndroid Build Coastguard Worker rfcomm.extended_address().Write(true);
529*61c4878aSAndroid Build Coastguard Worker rfcomm.command_response_direction().Write(
530*61c4878aSAndroid Build Coastguard Worker emboss::RfcommCommandResponseAndDirection::COMMAND_FROM_RESPONDER);
531*61c4878aSAndroid Build Coastguard Worker rfcomm.channel().Write(3);
532*61c4878aSAndroid Build Coastguard Worker rfcomm.control().Write(
533*61c4878aSAndroid Build Coastguard Worker emboss::RfcommFrameType::
534*61c4878aSAndroid Build Coastguard Worker UNNUMBERED_INFORMATION_WITH_HEADER_CHECK_AND_POLL_FINAL);
535*61c4878aSAndroid Build Coastguard Worker
536*61c4878aSAndroid Build Coastguard Worker rfcomm.length_extended_flag().Write(emboss::RfcommLengthExtended::EXTENDED);
537*61c4878aSAndroid Build Coastguard Worker rfcomm.length_extended().Write(expected_payload.size());
538*61c4878aSAndroid Build Coastguard Worker
539*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(rfcomm.has_credits().ValueOrDefault());
540*61c4878aSAndroid Build Coastguard Worker rfcomm.credits().Write(10);
541*61c4878aSAndroid Build Coastguard Worker
542*61c4878aSAndroid Build Coastguard Worker std::memcpy(rfcomm.information().BackingStorage().data(),
543*61c4878aSAndroid Build Coastguard Worker expected_payload.data(),
544*61c4878aSAndroid Build Coastguard Worker expected_payload.size());
545*61c4878aSAndroid Build Coastguard Worker rfcomm.fcs().Write(0x49);
546*61c4878aSAndroid Build Coastguard Worker
547*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, kFrameSize> expected{
548*61c4878aSAndroid Build Coastguard Worker // Address
549*61c4878aSAndroid Build Coastguard Worker 0x19,
550*61c4878aSAndroid Build Coastguard Worker // UIH Poll/Final
551*61c4878aSAndroid Build Coastguard Worker 0xFF,
552*61c4878aSAndroid Build Coastguard Worker // Information Length
553*61c4878aSAndroid Build Coastguard Worker 0x00,
554*61c4878aSAndroid Build Coastguard Worker 0x01,
555*61c4878aSAndroid Build Coastguard Worker // Credits
556*61c4878aSAndroid Build Coastguard Worker 0x0A,
557*61c4878aSAndroid Build Coastguard Worker // Payload/Information
558*61c4878aSAndroid Build Coastguard Worker 0xAB,
559*61c4878aSAndroid Build Coastguard Worker 0xCD,
560*61c4878aSAndroid Build Coastguard Worker 0xEF,
561*61c4878aSAndroid Build Coastguard Worker };
562*61c4878aSAndroid Build Coastguard Worker // FCS
563*61c4878aSAndroid Build Coastguard Worker expected[expected.size() - 1] = 0x49;
564*61c4878aSAndroid Build Coastguard Worker
565*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(expected[2], buffer[2]);
566*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(expected[3], buffer[3]);
567*61c4878aSAndroid Build Coastguard Worker
568*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(buffer, expected);
569*61c4878aSAndroid Build Coastguard Worker }
570*61c4878aSAndroid Build Coastguard Worker
571*61c4878aSAndroid Build Coastguard Worker } // namespace
572*61c4878aSAndroid Build Coastguard Worker } // namespace pw::bluetooth
573