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
15 #include "pw_bluetooth_sapphire/internal/host/testing/test_packets.h"
16
17 #include <pw_assert/check.h>
18
19 #include "pw_bluetooth/hci_common.emb.h"
20 #include "pw_bluetooth/hci_data.emb.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
22 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
23 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
24 #include "pw_bluetooth_sapphire/internal/host/hci-spec/vendor_protocol.h"
25 #include "pw_bluetooth_sapphire/internal/host/hci/bredr_connection_request.h"
26 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
27 #include "pw_string/string_builder.h"
28
29 namespace bt::testing {
30
31 namespace android_hci = bt::hci_spec::vendor::android;
32 namespace android_emb = pw::bluetooth::vendor::android_hci;
33
34 // Generates a blob of data that is unique to the size and starting value
GenDataBlob(size_t size,uint8_t starting_value)35 std::unique_ptr<std::vector<uint8_t>> GenDataBlob(size_t size,
36 uint8_t starting_value) {
37 auto result = std::make_unique<std::vector<uint8_t>>(size);
38 result->resize(size);
39 uint8_t next_value = starting_value;
40 for (auto& elem : *result) {
41 elem = next_value;
42 next_value += 7;
43 }
44 return result;
45 }
46
AcceptConnectionRequestPacket(DeviceAddress address)47 DynamicByteBuffer AcceptConnectionRequestPacket(DeviceAddress address) {
48 const auto addr = address.value().bytes();
49 return DynamicByteBuffer(StaticByteBuffer(
50 LowerBits(hci_spec::kAcceptConnectionRequest),
51 UpperBits(hci_spec::kAcceptConnectionRequest),
52 0x07, // parameter_total_size (7 bytes)
53 // peer BD_ADDR (6 bytes)
54 addr[0],
55 addr[1],
56 addr[2],
57 addr[3],
58 addr[4],
59 addr[5],
60 0x00 // Role (Become central)
61 ));
62 }
63
AuthenticationRequestedPacket(hci_spec::ConnectionHandle conn)64 DynamicByteBuffer AuthenticationRequestedPacket(
65 hci_spec::ConnectionHandle conn) {
66 return DynamicByteBuffer(StaticByteBuffer(
67 LowerBits(hci_spec::kAuthenticationRequested),
68 UpperBits(hci_spec::kAuthenticationRequested),
69 0x02, // parameter_total_size (2 bytes)
70 LowerBits(conn), // Connection_Handle
71 UpperBits(conn) // Connection_Handle
72 ));
73 }
74
CommandCompletePacket(hci_spec::OpCode opcode,pw::bluetooth::emboss::StatusCode status)75 DynamicByteBuffer CommandCompletePacket(
76 hci_spec::OpCode opcode, pw::bluetooth::emboss::StatusCode status) {
77 return DynamicByteBuffer(StaticByteBuffer(
78 hci_spec::kCommandCompleteEventCode,
79 0x04, // parameter_total_size (4 bytes)
80 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
81 LowerBits(opcode), // Command_Opcode
82 UpperBits(opcode), // Command_Opcode
83 status // Status
84 ));
85 }
86
CommandStatusPacket(hci_spec::OpCode op_code,pw::bluetooth::emboss::StatusCode status_code,uint8_t num_packets)87 DynamicByteBuffer CommandStatusPacket(
88 hci_spec::OpCode op_code,
89 pw::bluetooth::emboss::StatusCode status_code,
90 uint8_t num_packets) {
91 return DynamicByteBuffer(StaticByteBuffer(
92 hci_spec::kCommandStatusEventCode,
93 0x04, // parameter_total_size (4 bytes)
94 status_code, // Status
95 num_packets, // Num_HCI_Command_Packets allowed to be sent to controller
96 LowerBits(op_code), // Command_Opcode
97 UpperBits(op_code) // Command_Opcode
98 ));
99 }
100
ConnectionCompletePacket(DeviceAddress address,hci_spec::ConnectionHandle conn,pw::bluetooth::emboss::StatusCode status)101 DynamicByteBuffer ConnectionCompletePacket(
102 DeviceAddress address,
103 hci_spec::ConnectionHandle conn,
104 pw::bluetooth::emboss::StatusCode status) {
105 const auto addr = address.value().bytes();
106 return DynamicByteBuffer(StaticByteBuffer(
107 hci_spec::kConnectionCompleteEventCode,
108 0x0B, // parameter_total_size (11 bytes)
109 status, // Status
110 LowerBits(conn), // Connection_Handle
111 UpperBits(conn), // Connection_Handle
112 // peer BD_ADDR (6 bytes)
113 addr[0],
114 addr[1],
115 addr[2],
116 addr[3],
117 addr[4],
118 addr[5],
119 0x01, // Link_Type (ACL)
120 0x00 // Encryption_Enabled (Disabled)
121 ));
122 }
123
ConnectionRequestPacket(DeviceAddress address,hci_spec::LinkType link_type)124 DynamicByteBuffer ConnectionRequestPacket(DeviceAddress address,
125 hci_spec::LinkType link_type) {
126 const auto addr = address.value().bytes();
127 return DynamicByteBuffer(StaticByteBuffer(
128 hci_spec::kConnectionRequestEventCode,
129 0x0A, // parameter_total_size (10 bytes)
130 // peer BD_ADDR (6 bytes)
131 addr[0],
132 addr[1],
133 addr[2],
134 addr[3],
135 addr[4],
136 addr[5],
137 0x5A, // Class_Of_Device
138 0x42, // (Smart Phone minor class)
139 0x0C, // Networking, Capturing, Object Transfer, Telephony, LE Audio
140 link_type // Link_Type
141 ));
142 }
143
CreateConnectionPacket(DeviceAddress address)144 DynamicByteBuffer CreateConnectionPacket(DeviceAddress address) {
145 const auto addr = address.value().bytes();
146 return DynamicByteBuffer(StaticByteBuffer(
147 LowerBits(hci_spec::kCreateConnection),
148 UpperBits(hci_spec::kCreateConnection),
149 0x0d, // parameter_total_size (13 bytes)
150 // peer BD_ADDR (6 bytes)
151 addr[0],
152 addr[1],
153 addr[2],
154 addr[3],
155 addr[4],
156 addr[5],
157 LowerBits(hci::kEnableAllPacketTypes), // Packet_Type
158 UpperBits(hci::kEnableAllPacketTypes), // Packet_Type
159 0x02, // Page_Scan_Repetition_Mode (R2)
160 0x00, // Reserved
161 0x00, // Clock_Offset
162 0x00, // Clock_Offset
163 0x00 // Allow_Role_Switch (Not allowed)
164 ));
165 }
166
CreateConnectionCancelPacket(DeviceAddress address)167 DynamicByteBuffer CreateConnectionCancelPacket(DeviceAddress address) {
168 const auto addr = address.value().bytes();
169 return DynamicByteBuffer(
170 StaticByteBuffer(LowerBits(hci_spec::kCreateConnectionCancel),
171 UpperBits(hci_spec::kCreateConnectionCancel),
172 0x06, // parameter_total_size (6 bytes)
173 // peer BD_ADDR (6 bytes)
174 addr[0],
175 addr[1],
176 addr[2],
177 addr[3],
178 addr[4],
179 addr[5]));
180 }
181
DisconnectionCompletePacket(hci_spec::ConnectionHandle conn,pw::bluetooth::emboss::StatusCode reason)182 DynamicByteBuffer DisconnectionCompletePacket(
183 hci_spec::ConnectionHandle conn, pw::bluetooth::emboss::StatusCode reason) {
184 return DynamicByteBuffer(StaticByteBuffer(
185 hci_spec::kDisconnectionCompleteEventCode,
186 0x04, // parameter_total_size (4 bytes)
187 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
188 LowerBits(conn), // Connection_Handle
189 UpperBits(conn), // Connection_Handle
190 reason // Reason
191 ));
192 }
193
DisconnectPacket(hci_spec::ConnectionHandle conn,pw::bluetooth::emboss::StatusCode reason)194 DynamicByteBuffer DisconnectPacket(hci_spec::ConnectionHandle conn,
195 pw::bluetooth::emboss::StatusCode reason) {
196 return DynamicByteBuffer(StaticByteBuffer(
197 LowerBits(hci_spec::kDisconnect),
198 UpperBits(hci_spec::kDisconnect),
199 0x03, // parameter_total_size (3 bytes)
200 LowerBits(conn), // Connection_Handle
201 UpperBits(conn), // Connection_Handle
202 reason // Reason
203 ));
204 }
205
DisconnectStatusResponsePacket()206 DynamicByteBuffer DisconnectStatusResponsePacket() {
207 return DynamicByteBuffer(StaticByteBuffer(
208 hci_spec::kCommandStatusEventCode,
209 0x04, // parameter_total_size (3 bytes)
210 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
211 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
212 LowerBits(hci_spec::kDisconnect), // Command_Opcode
213 UpperBits(hci_spec::kDisconnect) // Command_Opcode
214 ));
215 }
216
EmptyCommandPacket(hci_spec::OpCode opcode)217 DynamicByteBuffer EmptyCommandPacket(hci_spec::OpCode opcode) {
218 return DynamicByteBuffer(
219 StaticByteBuffer(LowerBits(opcode), UpperBits(opcode), /*length=*/0));
220 }
221
EncryptionChangeEventPacket(pw::bluetooth::emboss::StatusCode status_code,hci_spec::ConnectionHandle conn,hci_spec::EncryptionStatus encryption_enabled)222 DynamicByteBuffer EncryptionChangeEventPacket(
223 pw::bluetooth::emboss::StatusCode status_code,
224 hci_spec::ConnectionHandle conn,
225 hci_spec::EncryptionStatus encryption_enabled) {
226 return DynamicByteBuffer(StaticByteBuffer(
227 hci_spec::kEncryptionChangeEventCode,
228 0x04, // parameter_total_size (4 bytes)
229 status_code, // Status
230 LowerBits(conn), // Connection_Handle
231 UpperBits(conn), // Connection_Handle
232 static_cast<uint8_t>(encryption_enabled) // Encryption_Enabled
233 ));
234 }
235
EnhancedAcceptSynchronousConnectionRequestPacket(DeviceAddress peer_address,bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter> params)236 DynamicByteBuffer EnhancedAcceptSynchronousConnectionRequestPacket(
237 DeviceAddress peer_address,
238 bt::StaticPacket<
239 pw::bluetooth::emboss::SynchronousConnectionParametersWriter> params) {
240 auto packet = hci::CommandPacket::New<
241 pw::bluetooth::emboss::
242 EnhancedAcceptSynchronousConnectionRequestCommandWriter>(
243 hci_spec::kEnhancedAcceptSynchronousConnectionRequest);
244 auto view = packet.view_t();
245
246 view.bd_addr().CopyFrom(peer_address.value().view());
247 view.connection_parameters().CopyFrom(params.view());
248
249 return DynamicByteBuffer(packet.data());
250 }
251
EnhancedSetupSynchronousConnectionPacket(hci_spec::ConnectionHandle conn,bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter> params)252 DynamicByteBuffer EnhancedSetupSynchronousConnectionPacket(
253 hci_spec::ConnectionHandle conn,
254 bt::StaticPacket<
255 pw::bluetooth::emboss::SynchronousConnectionParametersWriter> params) {
256 auto packet = hci::CommandPacket::New<
257 pw::bluetooth::emboss::EnhancedSetupSynchronousConnectionCommandWriter>(
258 hci_spec::kEnhancedSetupSynchronousConnection);
259
260 auto view = packet.view_t();
261 view.connection_handle().Write(conn);
262 view.connection_parameters().CopyFrom(params.view());
263
264 return DynamicByteBuffer(packet.data());
265 }
266
InquiryCommandPacket(uint16_t inquiry_length)267 DynamicByteBuffer InquiryCommandPacket(uint16_t inquiry_length) {
268 return DynamicByteBuffer(StaticByteBuffer(
269 LowerBits(hci_spec::kInquiry),
270 UpperBits(hci_spec::kInquiry),
271 0x05, // parameter_total_size (5 bytes)
272 0x33, // LAP (GIAC)
273 0x8B, // LAP (GIAC)
274 0x9E, // LAP (GIAC)
275 inquiry_length, // Inquiry_Length
276 0x00 // Num_Responses (Unlimited)
277 ));
278 }
279
IoCapabilityRequestNegativeReplyPacket(DeviceAddress address,pw::bluetooth::emboss::StatusCode status_code)280 DynamicByteBuffer IoCapabilityRequestNegativeReplyPacket(
281 DeviceAddress address, pw::bluetooth::emboss::StatusCode status_code) {
282 const auto addr = address.value().bytes();
283 return DynamicByteBuffer(StaticByteBuffer(
284 LowerBits(hci_spec::kIOCapabilityRequestNegativeReply),
285 UpperBits(hci_spec::kIOCapabilityRequestNegativeReply),
286 0x07, // parameter_total_size (7 bytes)
287 // peer BD_ADDR (6 bytes)
288 addr[0],
289 addr[1],
290 addr[2],
291 addr[3],
292 addr[4],
293 addr[5],
294 status_code // Reason
295 ));
296 }
297
IoCapabilityRequestNegativeReplyResponse(DeviceAddress address)298 DynamicByteBuffer IoCapabilityRequestNegativeReplyResponse(
299 DeviceAddress address) {
300 const auto addr = address.value().bytes();
301 return DynamicByteBuffer(StaticByteBuffer(
302 hci_spec::kCommandCompleteEventCode,
303 0x0A, // parameter_total_size (10 bytes)
304 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
305 LowerBits(hci_spec::kIOCapabilityRequestNegativeReply), // Command_Opcode
306 UpperBits(hci_spec::kIOCapabilityRequestNegativeReply), // Command_Opcode
307 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
308 // peer BD_ADDR (6 bytes)
309 addr[0],
310 addr[1],
311 addr[2],
312 addr[3],
313 addr[4],
314 addr[5]));
315 }
316
IoCapabilityRequestPacket(DeviceAddress address)317 DynamicByteBuffer IoCapabilityRequestPacket(DeviceAddress address) {
318 const auto addr = address.value().bytes();
319 return DynamicByteBuffer(
320 StaticByteBuffer(hci_spec::kIOCapabilityRequestEventCode,
321 0x06, // parameter_total_size (6 bytes)
322 // peer BD_ADDR (6 bytes)
323 addr[0],
324 addr[1],
325 addr[2],
326 addr[3],
327 addr[4],
328 addr[5]));
329 }
330
IoCapabilityRequestReplyPacket(DeviceAddress address,pw::bluetooth::emboss::IoCapability io_cap,pw::bluetooth::emboss::AuthenticationRequirements auth_req)331 DynamicByteBuffer IoCapabilityRequestReplyPacket(
332 DeviceAddress address,
333 pw::bluetooth::emboss::IoCapability io_cap,
334 pw::bluetooth::emboss::AuthenticationRequirements auth_req) {
335 const auto addr = address.value().bytes();
336 return DynamicByteBuffer(StaticByteBuffer(
337 LowerBits(hci_spec::kIOCapabilityRequestReply),
338 UpperBits(hci_spec::kIOCapabilityRequestReply),
339 0x09, // parameter_total_size (9 bytes)
340 // peer BD_ADDR (6 bytes)
341 addr[0],
342 addr[1],
343 addr[2],
344 addr[3],
345 addr[4],
346 addr[5],
347 io_cap, // IO_Capability
348 0x00, // OOB_Data_Present (Not present)
349 auth_req // Authentication_Requirements
350 ));
351 }
352
IoCapabilityRequestReplyResponse(DeviceAddress address)353 DynamicByteBuffer IoCapabilityRequestReplyResponse(DeviceAddress address) {
354 const auto addr = address.value().bytes();
355 return DynamicByteBuffer(StaticByteBuffer(
356 hci_spec::kCommandCompleteEventCode,
357 0x0A, // parameter_total_size (10 bytes)
358 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
359 LowerBits(hci_spec::kIOCapabilityRequestReply), // Command_Opcode
360 UpperBits(hci_spec::kIOCapabilityRequestReply), // Command_Opcode
361 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
362 // peer BD_ADDR (6 bytes)
363 addr[0],
364 addr[1],
365 addr[2],
366 addr[3],
367 addr[4],
368 addr[5]));
369 }
370
IoCapabilityResponsePacket(DeviceAddress address,pw::bluetooth::emboss::IoCapability io_cap,pw::bluetooth::emboss::AuthenticationRequirements auth_req)371 DynamicByteBuffer IoCapabilityResponsePacket(
372 DeviceAddress address,
373 pw::bluetooth::emboss::IoCapability io_cap,
374 pw::bluetooth::emboss::AuthenticationRequirements auth_req) {
375 const auto addr = address.value().bytes();
376 return DynamicByteBuffer(StaticByteBuffer(
377 hci_spec::kIOCapabilityResponseEventCode,
378 0x09, // parameter_total_size (9 bytes)
379 // peer BD_ADDR (6 bytes)
380 addr[0],
381 addr[1],
382 addr[2],
383 addr[3],
384 addr[4],
385 addr[5],
386 io_cap, // IO_Capability
387 0x00, // OOB_Data_Present (Not present)
388 auth_req // Authentication_Requirements
389 ));
390 }
391
IsoDataPacket(hci_spec::ConnectionHandle connection_handle,pw::bluetooth::emboss::IsoDataPbFlag pb_flag,std::optional<uint32_t> time_stamp,std::optional<uint16_t> packet_sequence_number,std::optional<uint16_t> iso_sdu_length,std::optional<pw::bluetooth::emboss::IsoDataPacketStatus> packet_status_flag,pw::span<const uint8_t> sdu_data)392 DynamicByteBuffer IsoDataPacket(
393 hci_spec::ConnectionHandle connection_handle,
394 pw::bluetooth::emboss::IsoDataPbFlag pb_flag,
395 std::optional<uint32_t> time_stamp,
396 std::optional<uint16_t> packet_sequence_number,
397 std::optional<uint16_t> iso_sdu_length,
398 std::optional<pw::bluetooth::emboss::IsoDataPacketStatus>
399 packet_status_flag,
400 pw::span<const uint8_t> sdu_data) {
401 size_t time_stamp_size = time_stamp.has_value() ? 4 : 0;
402 bool has_sdu_hdr =
403 (pb_flag == pw::bluetooth::emboss::IsoDataPbFlag::FIRST_FRAGMENT) ||
404 (pb_flag == pw::bluetooth::emboss::IsoDataPbFlag::COMPLETE_SDU);
405 size_t sdu_hdr_size = has_sdu_hdr ? 4 : 0;
406 size_t data_total_length = time_stamp_size + sdu_hdr_size + sdu_data.size();
407 size_t frame_total_size =
408 pw::bluetooth::emboss::IsoDataFrameHeaderView::SizeInBytes() +
409 data_total_length;
410 DynamicByteBuffer packet(frame_total_size);
411 auto view = pw::bluetooth::emboss::MakeIsoDataFramePacketView(
412 packet.mutable_data(), frame_total_size);
413
414 view.header().connection_handle().Write(connection_handle);
415 view.header().pb_flag().Write(pb_flag);
416 view.header().ts_flag().Write(
417 time_stamp.has_value()
418 ? pw::bluetooth::emboss::TsFlag::TIMESTAMP_PRESENT
419 : pw::bluetooth::emboss::TsFlag::TIMESTAMP_NOT_PRESENT);
420 view.header().data_total_length().Write(data_total_length);
421
422 if (time_stamp.has_value()) {
423 view.time_stamp().Write(*time_stamp);
424 }
425
426 if (has_sdu_hdr) {
427 PW_CHECK(packet_sequence_number.has_value());
428 PW_CHECK(iso_sdu_length.has_value());
429 PW_CHECK(packet_status_flag.has_value());
430 view.packet_sequence_number().Write(*packet_sequence_number);
431 view.iso_sdu_length().Write(*iso_sdu_length);
432 view.packet_status_flag().Write(*packet_status_flag);
433 }
434
435 // Write payload
436 memcpy(view.iso_sdu_fragment().BackingStorage().data(),
437 sdu_data.data(),
438 sdu_data.size());
439
440 return packet;
441 }
442
IsoDataFragments(hci_spec::ConnectionHandle connection_handle,std::optional<uint32_t> time_stamp,uint16_t packet_sequence_number,pw::bluetooth::emboss::IsoDataPacketStatus packet_status_flag,const std::vector<uint8_t> & sdu_data,const std::vector<size_t> & fragment_sizes)443 std::vector<DynamicByteBuffer> IsoDataFragments(
444 hci_spec::ConnectionHandle connection_handle,
445 std::optional<uint32_t> time_stamp,
446 uint16_t packet_sequence_number,
447 pw::bluetooth::emboss::IsoDataPacketStatus packet_status_flag,
448 const std::vector<uint8_t>& sdu_data,
449 const std::vector<size_t>& fragment_sizes) {
450 std::vector<DynamicByteBuffer> fragments;
451 uint16_t sdu_total_size = sdu_data.size();
452
453 size_t fragment_start = 0;
454 size_t fragment_end;
455 for (size_t fragment_size : fragment_sizes) {
456 fragment_end = fragment_start + fragment_size;
457 bool is_first = (fragment_start == 0);
458 bool is_last = (fragment_end == sdu_total_size);
459 pw::bluetooth::emboss::IsoDataPbFlag pb_flag;
460 if (is_first) {
461 pb_flag = is_last ? pw::bluetooth::emboss::IsoDataPbFlag::COMPLETE_SDU
462 : pw::bluetooth::emboss::IsoDataPbFlag::FIRST_FRAGMENT;
463 } else {
464 pb_flag =
465 is_last ? pw::bluetooth::emboss::IsoDataPbFlag::LAST_FRAGMENT
466 : pw::bluetooth::emboss::IsoDataPbFlag::INTERMEDIATE_FRAGMENT;
467 }
468 DynamicByteBuffer next_fragment = IsoDataPacket(
469 connection_handle,
470 pb_flag,
471 is_first ? time_stamp : std::nullopt,
472 is_first ? std::optional<uint16_t>(packet_sequence_number)
473 : std::nullopt,
474 is_first ? std::optional<uint16_t>(sdu_total_size) : std::nullopt,
475 is_first ? std::optional<pw::bluetooth::emboss::IsoDataPacketStatus>(
476 packet_status_flag)
477 : std::nullopt,
478 pw::span<const uint8_t>(sdu_data.data() + fragment_start,
479 fragment_size));
480 fragments.push_back(next_fragment);
481 fragment_start = fragment_end;
482 }
483
484 return fragments;
485 }
486
LEReadRemoteFeaturesCompletePacket(hci_spec::ConnectionHandle conn,hci_spec::LESupportedFeatures le_features)487 DynamicByteBuffer LEReadRemoteFeaturesCompletePacket(
488 hci_spec::ConnectionHandle conn,
489 hci_spec::LESupportedFeatures le_features) {
490 const BufferView features(&le_features, sizeof(le_features));
491 return DynamicByteBuffer(StaticByteBuffer(
492 hci_spec::kLEMetaEventCode,
493 0x0c, // parameter_total_size (12 bytes)
494 hci_spec::kLEReadRemoteFeaturesCompleteSubeventCode, // Subevent_Code
495 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
496 LowerBits(conn), // Connection_Handle
497 UpperBits(conn), // Connection_Handle
498 // LE_Features (8 bytes)
499 features[0],
500 features[1],
501 features[2],
502 features[3],
503 features[4],
504 features[5],
505 features[6],
506 features[7]));
507 }
508
LEReadRemoteFeaturesPacket(hci_spec::ConnectionHandle conn)509 DynamicByteBuffer LEReadRemoteFeaturesPacket(hci_spec::ConnectionHandle conn) {
510 return DynamicByteBuffer(StaticByteBuffer(
511 LowerBits(hci_spec::kLEReadRemoteFeatures),
512 UpperBits(hci_spec::kLEReadRemoteFeatures),
513 0x02, // parameter_total_size (2 bytes)
514 LowerBits(conn), // Connection_Handle
515 UpperBits(conn) // Connection_Handle
516 ));
517 }
518
LECisRequestEventPacket(hci_spec::ConnectionHandle acl_connection_handle,hci_spec::ConnectionHandle cis_connection_handle,hci_spec::CigIdentifier cig_id,hci_spec::CisIdentifier cis_id)519 DynamicByteBuffer LECisRequestEventPacket(
520 hci_spec::ConnectionHandle acl_connection_handle,
521 hci_spec::ConnectionHandle cis_connection_handle,
522 hci_spec::CigIdentifier cig_id,
523 hci_spec::CisIdentifier cis_id) {
524 return DynamicByteBuffer(StaticByteBuffer(
525 hci_spec::kLEMetaEventCode,
526 0x07, // parameter_total_size (7 bytes)
527 hci_spec::kLECISRequestSubeventCode, // Subevent_Code
528 LowerBits(acl_connection_handle), // ACL_Connection_Handle
529 UpperBits(acl_connection_handle), // ACL_Connection_Handle
530 LowerBits(cis_connection_handle), // CIS_Connection_Handle
531 UpperBits(cis_connection_handle), // CIS_Connection_Handle
532 cig_id, // CIG_ID
533 cis_id) // CIS_ID
534 );
535 }
536
LEAcceptCisRequestCommandPacket(hci_spec::ConnectionHandle cis_handle)537 DynamicByteBuffer LEAcceptCisRequestCommandPacket(
538 hci_spec::ConnectionHandle cis_handle) {
539 return DynamicByteBuffer(
540 StaticByteBuffer(LowerBits(hci_spec::kLEAcceptCISRequest),
541 UpperBits(hci_spec::kLEAcceptCISRequest),
542 0x02,
543 LowerBits(cis_handle),
544 UpperBits(cis_handle)));
545 }
546
LERejectCisRequestCommandPacket(hci_spec::ConnectionHandle cis_handle,pw::bluetooth::emboss::StatusCode reason)547 DynamicByteBuffer LERejectCisRequestCommandPacket(
548 hci_spec::ConnectionHandle cis_handle,
549 pw::bluetooth::emboss::StatusCode reason) {
550 return DynamicByteBuffer(
551 StaticByteBuffer(LowerBits(hci_spec::kLERejectCISRequest),
552 UpperBits(hci_spec::kLERejectCISRequest),
553 0x03, // parameter_total_size (3 bytes)
554 LowerBits(cis_handle), // Connection_Handle
555 UpperBits(cis_handle), // Connection_Handle
556 reason) // Reason
557 );
558 }
559
LERequestPeerScaCompletePacket(hci_spec::ConnectionHandle conn,pw::bluetooth::emboss::LESleepClockAccuracyRange sca)560 DynamicByteBuffer LERequestPeerScaCompletePacket(
561 hci_spec::ConnectionHandle conn,
562 pw::bluetooth::emboss::LESleepClockAccuracyRange sca) {
563 auto packet = hci::EventPacket::New<
564 pw::bluetooth::emboss::LERequestPeerSCACompleteSubeventWriter>(
565 hci_spec::kLEMetaEventCode);
566
567 auto view = packet.view_t();
568 view.le_meta_event().subevent_code().Write(
569 hci_spec::kLERequestPeerSCACompleteSubeventCode);
570 view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
571 view.connection_handle().Write(conn);
572 view.peer_clock_accuracy().Write(sca);
573
574 return DynamicByteBuffer(packet.data());
575 }
576
LECisEstablishedEventPacket(pw::bluetooth::emboss::StatusCode status,hci_spec::ConnectionHandle connection_handle,uint32_t cig_sync_delay_us,uint32_t cis_sync_delay_us,uint32_t transport_latency_c_to_p_us,uint32_t transport_latency_p_to_c_us,pw::bluetooth::emboss::IsoPhyType phy_c_to_p,pw::bluetooth::emboss::IsoPhyType phy_p_to_c,uint8_t nse,uint8_t bn_c_to_p,uint8_t bn_p_to_c,uint8_t ft_c_to_p,uint8_t ft_p_to_c,uint16_t max_pdu_c_to_p,uint16_t max_pdu_p_to_c,uint16_t iso_interval)577 DynamicByteBuffer LECisEstablishedEventPacket(
578 pw::bluetooth::emboss::StatusCode status,
579 hci_spec::ConnectionHandle connection_handle,
580 uint32_t cig_sync_delay_us,
581 uint32_t cis_sync_delay_us,
582 uint32_t transport_latency_c_to_p_us,
583 uint32_t transport_latency_p_to_c_us,
584 pw::bluetooth::emboss::IsoPhyType phy_c_to_p,
585 pw::bluetooth::emboss::IsoPhyType phy_p_to_c,
586 uint8_t nse,
587 uint8_t bn_c_to_p,
588 uint8_t bn_p_to_c,
589 uint8_t ft_c_to_p,
590 uint8_t ft_p_to_c,
591 uint16_t max_pdu_c_to_p,
592 uint16_t max_pdu_p_to_c,
593 uint16_t iso_interval) {
594 auto packet = hci::EventPacket::New<
595 pw::bluetooth::emboss::LECISEstablishedSubeventWriter>(
596 hci_spec::kLEMetaEventCode);
597 auto view = packet.view_t();
598
599 view.le_meta_event().subevent_code().Write(
600 hci_spec::kLECISEstablishedSubeventCode);
601 view.status().Write(status);
602 view.connection_handle().Write(connection_handle);
603 view.cig_sync_delay().Write(cig_sync_delay_us);
604 view.cis_sync_delay().Write(cis_sync_delay_us);
605 view.transport_latency_c_to_p().Write(transport_latency_c_to_p_us);
606 view.transport_latency_p_to_c().Write(transport_latency_p_to_c_us);
607 view.phy_c_to_p().Write(phy_c_to_p);
608 view.phy_p_to_c().Write(phy_p_to_c);
609 view.nse().Write(nse);
610 view.bn_c_to_p().Write(bn_c_to_p);
611 view.bn_p_to_c().Write(bn_p_to_c);
612 view.ft_c_to_p().Write(ft_c_to_p);
613 view.ft_p_to_c().Write(ft_p_to_c);
614 view.max_pdu_c_to_p().Write(max_pdu_c_to_p);
615 view.max_pdu_p_to_c().Write(max_pdu_p_to_c);
616 view.iso_interval().Write(iso_interval);
617
618 return DynamicByteBuffer(packet.data());
619 }
620
LESetupIsoDataPathPacket(hci_spec::ConnectionHandle connection_handle,pw::bluetooth::emboss::DataPathDirection direction,uint8_t data_path_id,bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter> codec_id,uint32_t controller_delay,const std::optional<std::vector<uint8_t>> & codec_configuration)621 DynamicByteBuffer LESetupIsoDataPathPacket(
622 hci_spec::ConnectionHandle connection_handle,
623 pw::bluetooth::emboss::DataPathDirection direction,
624 uint8_t data_path_id,
625 bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter> codec_id,
626 uint32_t controller_delay,
627 const std::optional<std::vector<uint8_t>>& codec_configuration) {
628 size_t packet_size =
629 pw::bluetooth::emboss::LESetupISODataPathCommand::MinSizeInBytes() +
630 (codec_configuration.has_value() ? codec_configuration->size() : 0);
631 auto packet = hci::CommandPacket::New<
632 pw::bluetooth::emboss::LESetupISODataPathCommandWriter>(
633 hci_spec::kLESetupISODataPath, packet_size);
634 auto view = packet.view_t();
635 view.connection_handle().Write(connection_handle);
636 view.data_path_direction().Write(direction);
637 view.data_path_id().Write(data_path_id);
638 view.codec_id().CopyFrom(
639 const_cast<bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter>&>(
640 codec_id)
641 .view());
642 view.controller_delay().Write(controller_delay);
643 if (codec_configuration.has_value()) {
644 view.codec_configuration_length().Write(codec_configuration->size());
645 std::memcpy(view.codec_configuration().BackingStorage().data(),
646 codec_configuration->data(),
647 codec_configuration->size());
648 } else {
649 view.codec_configuration_length().Write(0);
650 }
651 return DynamicByteBuffer(packet.data());
652 }
653
LESetupIsoDataPathResponse(pw::bluetooth::emboss::StatusCode status,hci_spec::ConnectionHandle connection_handle)654 DynamicByteBuffer LESetupIsoDataPathResponse(
655 pw::bluetooth::emboss::StatusCode status,
656 hci_spec::ConnectionHandle connection_handle) {
657 return DynamicByteBuffer(StaticByteBuffer(
658 hci_spec::kCommandCompleteEventCode,
659 0x06, // parameter_total_size (6 bytes)
660 0xF0, // Num_HCI_CommandPackets allowed to be sent to controller (240)
661 LowerBits(hci_spec::kLESetupISODataPath),
662 UpperBits(hci_spec::kLESetupISODataPath),
663 status,
664 LowerBits(connection_handle),
665 UpperBits(connection_handle)));
666 }
667
LERequestPeerScaPacket(hci_spec::ConnectionHandle conn)668 DynamicByteBuffer LERequestPeerScaPacket(hci_spec::ConnectionHandle conn) {
669 auto packet = hci::CommandPacket::New<
670 pw::bluetooth::emboss::LERequestPeerSCACommandWriter>(
671 hci_spec::kLERequestPeerSCA);
672 auto view = packet.view_t();
673 view.connection_handle().Write(conn);
674 return DynamicByteBuffer(packet.data());
675 }
676
LEStartEncryptionPacket(hci_spec::ConnectionHandle conn,uint64_t random_number,uint16_t encrypted_diversifier,UInt128 ltk)677 DynamicByteBuffer LEStartEncryptionPacket(hci_spec::ConnectionHandle conn,
678 uint64_t random_number,
679 uint16_t encrypted_diversifier,
680 UInt128 ltk) {
681 const BufferView rand(&random_number, sizeof(random_number));
682 return DynamicByteBuffer(StaticByteBuffer(
683 LowerBits(hci_spec::kLEStartEncryption),
684 UpperBits(hci_spec::kLEStartEncryption),
685 0x1c, // parameter_total_size (28 bytes)
686 LowerBits(conn), // Connection_Handle
687 UpperBits(conn), // Connection_Handle
688 // Random_Number (8 bytes)
689 rand[0],
690 rand[1],
691 rand[2],
692 rand[3],
693 rand[4],
694 rand[5],
695 rand[6],
696 rand[7],
697 LowerBits(encrypted_diversifier), // Encrypted_Diversifier
698 UpperBits(encrypted_diversifier), // Encrypted_Diversifier
699 // Long_Term_Key (16 bytes)
700 ltk[0],
701 ltk[1],
702 ltk[2],
703 ltk[3],
704 ltk[4],
705 ltk[5],
706 ltk[6],
707 ltk[7],
708 ltk[8],
709 ltk[9],
710 ltk[10],
711 ltk[11],
712 ltk[12],
713 ltk[13],
714 ltk[14],
715 ltk[15]));
716 }
717
LinkKeyNotificationPacket(DeviceAddress address,UInt128 link_key,hci_spec::LinkKeyType key_type)718 DynamicByteBuffer LinkKeyNotificationPacket(DeviceAddress address,
719 UInt128 link_key,
720 hci_spec::LinkKeyType key_type) {
721 const auto addr = address.value().bytes();
722 return DynamicByteBuffer(StaticByteBuffer(
723 hci_spec::kLinkKeyNotificationEventCode,
724 0x17, // parameter_total_size (23 bytes)
725 // peer BD_ADDR (6 bytes)
726 addr[0],
727 addr[1],
728 addr[2],
729 addr[3],
730 addr[4],
731 addr[5],
732 // Link_Key (16 bytes)
733 link_key[0],
734 link_key[1],
735 link_key[2],
736 link_key[3],
737 link_key[4],
738 link_key[5],
739 link_key[6],
740 link_key[7],
741 link_key[8],
742 link_key[9],
743 link_key[10],
744 link_key[11],
745 link_key[12],
746 link_key[13],
747 link_key[14],
748 link_key[15],
749 key_type // Key_Type
750 ));
751 }
752
LinkKeyRequestPacket(DeviceAddress address)753 DynamicByteBuffer LinkKeyRequestPacket(DeviceAddress address) {
754 const auto addr = address.value().bytes();
755 return DynamicByteBuffer(
756 StaticByteBuffer(hci_spec::kLinkKeyRequestEventCode,
757 0x06, // parameter_total_size (6 bytes)
758 // peer BD_ADDR (6 bytes)
759 addr[0],
760 addr[1],
761 addr[2],
762 addr[3],
763 addr[4],
764 addr[5]));
765 }
766
LinkKeyRequestNegativeReplyPacket(DeviceAddress address)767 DynamicByteBuffer LinkKeyRequestNegativeReplyPacket(DeviceAddress address) {
768 const auto addr = address.value().bytes();
769 return DynamicByteBuffer(
770 StaticByteBuffer(LowerBits(hci_spec::kLinkKeyRequestNegativeReply),
771 UpperBits(hci_spec::kLinkKeyRequestNegativeReply),
772 0x06, // parameter_total_size (6 bytes)
773 // peer BD_ADDR (6 bytes)
774 addr[0],
775 addr[1],
776 addr[2],
777 addr[3],
778 addr[4],
779 addr[5]));
780 }
781
LinkKeyRequestNegativeReplyResponse(DeviceAddress address)782 DynamicByteBuffer LinkKeyRequestNegativeReplyResponse(DeviceAddress address) {
783 const auto addr = address.value().bytes();
784 return DynamicByteBuffer(StaticByteBuffer(
785 hci_spec::kCommandCompleteEventCode,
786 0x0A, // parameter_total_size (10 bytes)
787 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
788 LowerBits(hci_spec::kLinkKeyRequestNegativeReply), // Command_Opcode
789 UpperBits(hci_spec::kLinkKeyRequestNegativeReply), // Command_Opcode
790 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
791 // peer BD_ADDR (6 bytes)
792 addr[0],
793 addr[1],
794 addr[2],
795 addr[3],
796 addr[4],
797 addr[5]));
798 }
799
LinkKeyRequestReplyPacket(DeviceAddress address,UInt128 link_key)800 DynamicByteBuffer LinkKeyRequestReplyPacket(DeviceAddress address,
801 UInt128 link_key) {
802 const auto addr = address.value().bytes();
803 return DynamicByteBuffer(
804 StaticByteBuffer(LowerBits(hci_spec::kLinkKeyRequestReply),
805 UpperBits(hci_spec::kLinkKeyRequestReply),
806 0x16, // parameter_total_size (22 bytes)
807 // peer BD_ADDR (6 bytes)
808 addr[0],
809 addr[1],
810 addr[2],
811 addr[3],
812 addr[4],
813 addr[5],
814 // Link_Key (16 bytes)
815 link_key[0],
816 link_key[1],
817 link_key[2],
818 link_key[3],
819 link_key[4],
820 link_key[5],
821 link_key[6],
822 link_key[7],
823 link_key[8],
824 link_key[9],
825 link_key[10],
826 link_key[11],
827 link_key[12],
828 link_key[13],
829 link_key[14],
830 link_key[15]));
831 }
832
LinkKeyRequestReplyResponse(DeviceAddress address)833 DynamicByteBuffer LinkKeyRequestReplyResponse(DeviceAddress address) {
834 const auto addr = address.value().bytes();
835 return DynamicByteBuffer(StaticByteBuffer(
836 hci_spec::kCommandCompleteEventCode,
837 0x0A, // parameter_total_size (10 bytes)
838 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
839 LowerBits(hci_spec::kLinkKeyRequestReply), // Command_Opcode
840 UpperBits(hci_spec::kLinkKeyRequestReply), // Command_Opcode
841 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
842 // peer BD_ADDR (6 bytes)
843 addr[0],
844 addr[1],
845 addr[2],
846 addr[3],
847 addr[4],
848 addr[5]));
849 }
850
NumberOfCompletedPacketsPacket(hci_spec::ConnectionHandle conn,uint16_t num_packets)851 DynamicByteBuffer NumberOfCompletedPacketsPacket(
852 hci_spec::ConnectionHandle conn, uint16_t num_packets) {
853 return DynamicByteBuffer(StaticByteBuffer(
854 0x13,
855 0x05, // Number Of Completed Packet HCI event header, parameters length
856 0x01, // Num_Handles
857 LowerBits(conn), // Connection_Handle
858 UpperBits(conn), // Connection_Handle
859 LowerBits(num_packets), // Num_Completed_Packets
860 UpperBits(num_packets) // Num_Completed_Packets
861 ));
862 }
863
NumberOfCompletedPacketsPacketWithInvalidSize(hci_spec::ConnectionHandle conn,uint16_t num_packets)864 DynamicByteBuffer NumberOfCompletedPacketsPacketWithInvalidSize(
865 hci_spec::ConnectionHandle conn, uint16_t num_packets) {
866 return DynamicByteBuffer(StaticByteBuffer(
867 0x13,
868 0x05, // Number Of Completed Packet HCI event header, parameters length
869 0x03, // Num_Handles
870 LowerBits(conn), // Connection_Handle
871 UpperBits(conn), // Connection_Handle
872 LowerBits(num_packets), // Num_Completed_Packets
873 UpperBits(num_packets) // Num_Completed_Packets
874 ));
875 }
876
PinCodeRequestPacket(DeviceAddress address)877 DynamicByteBuffer PinCodeRequestPacket(DeviceAddress address) {
878 const auto addr = address.value().bytes();
879 return DynamicByteBuffer(
880 StaticByteBuffer(hci_spec::kPinCodeRequestEventCode,
881 0x06, // parameter_total_size (6 bytes)
882 // peer BD_ADDR (6 bytes)
883 addr[0],
884 addr[1],
885 addr[2],
886 addr[3],
887 addr[4],
888 addr[5]));
889 }
890
PinCodeRequestNegativeReplyPacket(DeviceAddress address)891 DynamicByteBuffer PinCodeRequestNegativeReplyPacket(DeviceAddress address) {
892 const auto addr = address.value().bytes();
893 return DynamicByteBuffer(
894 StaticByteBuffer(LowerBits(hci_spec::kPinCodeRequestNegativeReply),
895 UpperBits(hci_spec::kPinCodeRequestNegativeReply),
896 0x06, // parameter_total_size (6 bytes)
897 // peer BD_ADDR (6 bytes)
898 addr[0],
899 addr[1],
900 addr[2],
901 addr[3],
902 addr[4],
903 addr[5]));
904 }
905
PinCodeRequestNegativeReplyResponse(DeviceAddress address)906 DynamicByteBuffer PinCodeRequestNegativeReplyResponse(DeviceAddress address) {
907 const auto addr = address.value().bytes();
908 return DynamicByteBuffer(StaticByteBuffer(
909 hci_spec::kCommandCompleteEventCode,
910 0x0A, // parameter_total_size (10 bytes)
911 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
912 LowerBits(hci_spec::kPinCodeRequestNegativeReply), // Command_Opcode
913 UpperBits(hci_spec::kPinCodeRequestNegativeReply), // Command_Opcode
914 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
915 // peer BD_ADDR (6 bytes)
916 addr[0],
917 addr[1],
918 addr[2],
919 addr[3],
920 addr[4],
921 addr[5]));
922 }
923
PinCodeRequestReplyPacket(DeviceAddress address,uint8_t pin_length,std::string pin_code)924 DynamicByteBuffer PinCodeRequestReplyPacket(DeviceAddress address,
925 uint8_t pin_length,
926 std::string pin_code) {
927 const auto addr = address.value().bytes();
928
929 StaticByteBuffer<16> pin;
930 pin.Write(BufferView(pin_code));
931
932 return DynamicByteBuffer(
933 StaticByteBuffer(LowerBits(hci_spec::kPinCodeRequestReply),
934 UpperBits(hci_spec::kPinCodeRequestReply),
935 0x17, // parameter_total_size (23 bytes)
936 // peer BD_ADDR (6 bytes)
937 addr[0],
938 addr[1],
939 addr[2],
940 addr[3],
941 addr[4],
942 addr[5],
943 pin_length, // PIN_Code_Length
944 // PIN_Code
945 pin[0],
946 pin[1],
947 pin[2],
948 pin[3],
949 pin[4],
950 pin[5],
951 pin[6],
952 pin[7],
953 pin[8],
954 pin[9],
955 pin[10],
956 pin[11],
957 pin[12],
958 pin[13],
959 pin[14],
960 pin[15]));
961 }
962
PinCodeRequestReplyResponse(DeviceAddress address)963 DynamicByteBuffer PinCodeRequestReplyResponse(DeviceAddress address) {
964 const auto addr = address.value().bytes();
965 return DynamicByteBuffer(StaticByteBuffer(
966 hci_spec::kCommandCompleteEventCode,
967 0x0A, // parameter_total_size (10 bytes)
968 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
969 LowerBits(hci_spec::kPinCodeRequestReply), // Command_Opcode
970 UpperBits(hci_spec::kPinCodeRequestReply), // Command_Opcode
971 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
972 // peer BD_ADDR (6 bytes)
973 addr[0],
974 addr[1],
975 addr[2],
976 addr[3],
977 addr[4],
978 addr[5]));
979 }
980
ReadRemoteExtended1CompletePacket(hci_spec::ConnectionHandle conn)981 DynamicByteBuffer ReadRemoteExtended1CompletePacket(
982 hci_spec::ConnectionHandle conn) {
983 return DynamicByteBuffer(StaticByteBuffer(
984 hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
985 0x0D, // parameter_total_size (13 bytes)
986 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
987 LowerBits(conn), // Connection_Handle
988 UpperBits(conn), // Connection_Handle
989 0x01, // Page_Number
990 0x03, // Max_Page_Number (3 pages)
991 // Extended_LMP_Features (8 bytes)
992 0x0F,
993 0x00,
994 0x00,
995 0x00,
996 0x00,
997 0x00,
998 0x00,
999 0x00
1000 // lmp_features_page1: Secure Simple Pairing (Host Support), LE Supported
1001 // (Host), Previously used, Secure Connections (Host Support)
1002 ));
1003 }
1004
ReadRemoteExtended1CompletePacketNoSsp(hci_spec::ConnectionHandle conn)1005 DynamicByteBuffer ReadRemoteExtended1CompletePacketNoSsp(
1006 hci_spec::ConnectionHandle conn) {
1007 return DynamicByteBuffer(StaticByteBuffer(
1008 hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
1009 0x0D, // parameter_total_size (13 bytes)
1010 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1011 LowerBits(conn), // Connection_Handle
1012 UpperBits(conn), // Connection_Handle
1013 0x01, // Page_Number
1014 0x03, // Max_Page_Number (3 pages)
1015 // Extended_LMP_Features (8 bytes)
1016 0x0E,
1017 0x00,
1018 0x00,
1019 0x00,
1020 0x00,
1021 0x00,
1022 0x00,
1023 0x00
1024 // lmp_features_page1: LE Supported (Host), Previously used, Secure
1025 // Connections (Host Support)
1026 ));
1027 }
1028
ReadRemoteExtended1Packet(hci_spec::ConnectionHandle conn)1029 DynamicByteBuffer ReadRemoteExtended1Packet(hci_spec::ConnectionHandle conn) {
1030 return DynamicByteBuffer(StaticByteBuffer(
1031 LowerBits(hci_spec::kReadRemoteExtendedFeatures),
1032 UpperBits(hci_spec::kReadRemoteExtendedFeatures),
1033 0x03, // parameter_total_size (3 bytes)
1034 LowerBits(conn), // Connection_Handle
1035 UpperBits(conn), // Connection_Handle
1036 0x01 // Page_Number (1)
1037 ));
1038 }
1039
ReadRemoteExtended2CompletePacket(hci_spec::ConnectionHandle conn)1040 DynamicByteBuffer ReadRemoteExtended2CompletePacket(
1041 hci_spec::ConnectionHandle conn) {
1042 return DynamicByteBuffer(StaticByteBuffer(
1043 hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode,
1044 0x0D, // parameter_total_size (13 bytes)
1045 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1046 LowerBits(conn), // Connection_Handle
1047 UpperBits(conn), // Connection_Handle
1048 0x02, // Page_Number
1049 0x03, // Max_Page_Number (3 pages)
1050 // Extended_LMP_Features (8 bytes)
1051 0x00,
1052 0x00,
1053 0x00,
1054 0x00,
1055 0x02,
1056 0x00,
1057 0xFF,
1058 0x00
1059 // lmp_features_page2: All the bits should be ignored
1060 ));
1061 }
1062
ReadRemoteExtended2Packet(hci_spec::ConnectionHandle conn)1063 DynamicByteBuffer ReadRemoteExtended2Packet(hci_spec::ConnectionHandle conn) {
1064 return DynamicByteBuffer(StaticByteBuffer(
1065 LowerBits(hci_spec::kReadRemoteExtendedFeatures),
1066 UpperBits(hci_spec::kReadRemoteExtendedFeatures),
1067 0x03, // parameter_total_size (3 bytes)
1068 LowerBits(conn), // Connection_Handle
1069 UpperBits(conn), // Connection_Handle
1070 0x02 // Page_Number (2)
1071 ));
1072 }
1073
ReadRemoteVersionInfoCompletePacket(hci_spec::ConnectionHandle conn)1074 DynamicByteBuffer ReadRemoteVersionInfoCompletePacket(
1075 hci_spec::ConnectionHandle conn) {
1076 return DynamicByteBuffer(StaticByteBuffer(
1077 hci_spec::kReadRemoteVersionInfoCompleteEventCode,
1078 0x08, // parameter_total_size (8 bytes)
1079 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1080 LowerBits(conn), // Connection_Handle
1081 UpperBits(conn), // Connection_Handle
1082 pw::bluetooth::emboss::CoreSpecificationVersion::V4_2, // Version
1083 0xE0, // Company_Identifier (Google)
1084 0x00, // Company_Identifier (Google)
1085 0xAD, // Subversion (Anything)
1086 0xDE // Subversion (Anything)
1087 ));
1088 }
1089
ReadRemoteVersionInfoPacket(hci_spec::ConnectionHandle conn)1090 DynamicByteBuffer ReadRemoteVersionInfoPacket(hci_spec::ConnectionHandle conn) {
1091 return DynamicByteBuffer(StaticByteBuffer(
1092 LowerBits(hci_spec::kReadRemoteVersionInfo),
1093 UpperBits(hci_spec::kReadRemoteVersionInfo),
1094 0x02, // parameter_total_size (2 bytes)
1095 LowerBits(conn), // Connection_Handle
1096 UpperBits(conn) // Connection_Handle
1097 ));
1098 }
1099
ReadRemoteSupportedFeaturesCompletePacket(hci_spec::ConnectionHandle conn,bool extended_features)1100 DynamicByteBuffer ReadRemoteSupportedFeaturesCompletePacket(
1101 hci_spec::ConnectionHandle conn, bool extended_features) {
1102 return DynamicByteBuffer(StaticByteBuffer(
1103 hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode,
1104 0x0B, // parameter_total_size (11 bytes)
1105 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1106 LowerBits(conn), // Connection_Handle
1107 UpperBits(conn), // Connection_Handle
1108 // LMP_Features (8 bytes)
1109 0xFF,
1110 0x00,
1111 0x00,
1112 0x00,
1113 0x04,
1114 0x00,
1115 0x08,
1116 (extended_features ? 0x80 : 0x00)
1117 // lmp_features_page0: 3 slot packets, 5 slot packets, Encryption, Slot
1118 // Offset, Timing Accuracy, Role Switch, Hold Mode, Sniff Mode, LE
1119 // Supported (Controller), Secure Simple Pairing (Controller Support),
1120 // Extended Features if enabled
1121 ));
1122 }
1123
ReadRemoteSupportedFeaturesPacket(hci_spec::ConnectionHandle conn)1124 DynamicByteBuffer ReadRemoteSupportedFeaturesPacket(
1125 hci_spec::ConnectionHandle conn) {
1126 return DynamicByteBuffer(StaticByteBuffer(
1127 LowerBits(hci_spec::kReadRemoteSupportedFeatures),
1128 UpperBits(hci_spec::kReadRemoteSupportedFeatures),
1129 0x02, // parameter_total_size (2 bytes)
1130 LowerBits(conn), // Connection_Handle
1131 UpperBits(conn) // Connection_Handle
1132 ));
1133 }
1134
ReadScanEnable()1135 DynamicByteBuffer ReadScanEnable() {
1136 return DynamicByteBuffer(StaticByteBuffer(
1137 LowerBits(hci_spec::kReadScanEnable),
1138 UpperBits(hci_spec::kReadScanEnable),
1139 0x00 // No parameters
1140 ));
1141 }
1142
ReadScanEnableResponse(uint8_t scan_enable)1143 DynamicByteBuffer ReadScanEnableResponse(uint8_t scan_enable) {
1144 return DynamicByteBuffer(StaticByteBuffer(
1145 hci_spec::kCommandCompleteEventCode,
1146 0x05, // parameter_total_size (5 bytes)
1147 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
1148 LowerBits(hci_spec::kReadScanEnable), // Command_Opcode
1149 UpperBits(hci_spec::kReadScanEnable), // Command_Opcode
1150 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1151 scan_enable // Scan_Enable
1152 ));
1153 }
1154
RejectConnectionRequestPacket(DeviceAddress address,pw::bluetooth::emboss::StatusCode reason)1155 DynamicByteBuffer RejectConnectionRequestPacket(
1156 DeviceAddress address, pw::bluetooth::emboss::StatusCode reason) {
1157 const auto addr = address.value().bytes();
1158 return DynamicByteBuffer(StaticByteBuffer(
1159 LowerBits(hci_spec::kRejectConnectionRequest),
1160 UpperBits(hci_spec::kRejectConnectionRequest),
1161 0x07, // parameter_total_size (7 bytes)
1162 // peer BD_ADDR (6 bytes)
1163 addr[0],
1164 addr[1],
1165 addr[2],
1166 addr[3],
1167 addr[4],
1168 addr[5],
1169 reason // Reason
1170 ));
1171 }
RejectSynchronousConnectionRequest(DeviceAddress address,pw::bluetooth::emboss::StatusCode status_code)1172 DynamicByteBuffer RejectSynchronousConnectionRequest(
1173 DeviceAddress address, pw::bluetooth::emboss::StatusCode status_code) {
1174 const auto addr = address.value().bytes();
1175 return DynamicByteBuffer(StaticByteBuffer(
1176 LowerBits(hci_spec::kRejectSynchronousConnectionRequest),
1177 UpperBits(hci_spec::kRejectSynchronousConnectionRequest),
1178 0x07, // parameter_total_size (7 bytes)
1179 // peer BD_ADDR (6 bytes)
1180 addr[0],
1181 addr[1],
1182 addr[2],
1183 addr[3],
1184 addr[4],
1185 addr[5],
1186 status_code // Reason
1187 ));
1188 }
1189
RemoteNameRequestCompletePacket(DeviceAddress address,const std::string & name)1190 DynamicByteBuffer RemoteNameRequestCompletePacket(DeviceAddress address,
1191 const std::string& name) {
1192 const auto addr = address.value().bytes();
1193 auto event = DynamicByteBuffer(
1194 pw::bluetooth::emboss::RemoteNameRequestCompleteEventView::
1195 IntrinsicSizeInBytes()
1196 .Read());
1197 event.SetToZeros();
1198 const StaticByteBuffer header(
1199 hci_spec::kRemoteNameRequestCompleteEventCode,
1200 0xff, // parameter_total_size (255 bytes)
1201 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1202 // peer BD_ADDR (6 bytes)
1203 addr[0],
1204 addr[1],
1205 addr[2],
1206 addr[3],
1207 addr[4],
1208 addr[5]);
1209 header.Copy(&event);
1210 event.Write(reinterpret_cast<const uint8_t*>(name.data()),
1211 name.size(),
1212 header.size());
1213 return event;
1214 }
1215
RemoteNameRequestPacket(DeviceAddress address)1216 DynamicByteBuffer RemoteNameRequestPacket(DeviceAddress address) {
1217 const auto addr = address.value().bytes();
1218 return DynamicByteBuffer(StaticByteBuffer(
1219 LowerBits(hci_spec::kRemoteNameRequest),
1220 UpperBits(hci_spec::kRemoteNameRequest),
1221 0x0a, // parameter_total_size (10 bytes)
1222 // peer BD_ADDR (6 bytes)
1223 addr[0],
1224 addr[1],
1225 addr[2],
1226 addr[3],
1227 addr[4],
1228 addr[5],
1229 0x00, // Page_Scan_Repetition_Mode (R0)
1230 0x00, // Reserved
1231 0x00, // Clock_Offset
1232 0x00 // Clock_Offset
1233 ));
1234 }
1235
RoleChangePacket(DeviceAddress address,pw::bluetooth::emboss::ConnectionRole role,pw::bluetooth::emboss::StatusCode status)1236 DynamicByteBuffer RoleChangePacket(DeviceAddress address,
1237 pw::bluetooth::emboss::ConnectionRole role,
1238 pw::bluetooth::emboss::StatusCode status) {
1239 const auto addr = address.value().bytes();
1240 return DynamicByteBuffer(StaticByteBuffer(
1241 hci_spec::kRoleChangeEventCode,
1242 0x08, // parameter_total_size (8 bytes)
1243 status, // Status
1244 // peer BD_ADDR (6 bytes)
1245 addr[0],
1246 addr[1],
1247 addr[2],
1248 addr[3],
1249 addr[4],
1250 addr[5],
1251 role // Role
1252 ));
1253 }
1254
ScoDataPacket(hci_spec::ConnectionHandle conn,hci_spec::SynchronousDataPacketStatusFlag flag,const BufferView & payload,std::optional<uint8_t> payload_length_override)1255 DynamicByteBuffer ScoDataPacket(
1256 hci_spec::ConnectionHandle conn,
1257 hci_spec::SynchronousDataPacketStatusFlag flag,
1258 const BufferView& payload,
1259 std::optional<uint8_t> payload_length_override) {
1260 // Flag is bits 4-5 in the higher octet of |handle_and_flags|, i.e.
1261 // 0b00xx000000000000.
1262 conn |= static_cast<uint8_t>(flag) << 12;
1263 StaticByteBuffer header(
1264 LowerBits(conn),
1265 UpperBits(conn),
1266 payload_length_override ? *payload_length_override : payload.size());
1267 DynamicByteBuffer out(header.size() + payload.size());
1268 header.Copy(&out);
1269 MutableBufferView payload_view = out.mutable_view(header.size());
1270 payload.Copy(&payload_view);
1271 return out;
1272 }
1273
SetConnectionEncryption(hci_spec::ConnectionHandle conn,bool enable)1274 DynamicByteBuffer SetConnectionEncryption(hci_spec::ConnectionHandle conn,
1275 bool enable) {
1276 return DynamicByteBuffer(StaticByteBuffer(
1277 LowerBits(hci_spec::kSetConnectionEncryption),
1278 UpperBits(hci_spec::kSetConnectionEncryption),
1279 0x03, // parameter_total_size (3 bytes)
1280 LowerBits(conn), // Connection_Handle
1281 UpperBits(conn), // Connection_Handle
1282 static_cast<uint8_t>(enable) // Encryption_Enable
1283 ));
1284 }
1285
SimplePairingCompletePacket(DeviceAddress address,pw::bluetooth::emboss::StatusCode status_code)1286 DynamicByteBuffer SimplePairingCompletePacket(
1287 DeviceAddress address, pw::bluetooth::emboss::StatusCode status_code) {
1288 const auto addr = address.value().bytes();
1289 return DynamicByteBuffer(
1290 StaticByteBuffer(hci_spec::kSimplePairingCompleteEventCode,
1291 0x07, // parameter_total_size (7 bytes)
1292 status_code,
1293 // peer BD_ADDR (6 bytes)
1294 addr[0],
1295 addr[1],
1296 addr[2],
1297 addr[3],
1298 addr[4],
1299 addr[5]));
1300 }
1301
StartA2dpOffloadRequest(const l2cap::A2dpOffloadManager::Configuration & config,hci_spec::ConnectionHandle connection_handle,l2cap::ChannelId l2cap_channel_id,uint16_t l2cap_mtu_size)1302 DynamicByteBuffer StartA2dpOffloadRequest(
1303 const l2cap::A2dpOffloadManager::Configuration& config,
1304 hci_spec::ConnectionHandle connection_handle,
1305 l2cap::ChannelId l2cap_channel_id,
1306 uint16_t l2cap_mtu_size) {
1307 constexpr size_t kPacketSize =
1308 android_emb::StartA2dpOffloadCommand::MaxSizeInBytes();
1309 auto packet =
1310 hci::CommandPacket::New<android_emb::StartA2dpOffloadCommandWriter>(
1311 android_hci::kA2dpOffloadCommand, kPacketSize);
1312 auto view = packet.view_t();
1313
1314 view.vendor_command().sub_opcode().Write(
1315 android_hci::kStartA2dpOffloadCommandSubopcode);
1316 view.codec_type().Write(config.codec);
1317 view.max_latency().Write(config.max_latency);
1318 view.scms_t_enable().CopyFrom(
1319 const_cast<l2cap::A2dpOffloadManager::Configuration&>(config)
1320 .scms_t_enable.view());
1321 view.sampling_frequency().Write(config.sampling_frequency);
1322 view.bits_per_sample().Write(config.bits_per_sample);
1323 view.channel_mode().Write(config.channel_mode);
1324 view.encoded_audio_bitrate().Write(config.encoded_audio_bit_rate);
1325 view.connection_handle().Write(connection_handle);
1326 view.l2cap_channel_id().Write(l2cap_channel_id);
1327 view.l2cap_mtu_size().Write(l2cap_mtu_size);
1328
1329 switch (config.codec) {
1330 case android_emb::A2dpCodecType::SBC:
1331 view.sbc_codec_information().CopyFrom(
1332 const_cast<l2cap::A2dpOffloadManager::Configuration&>(config)
1333 .sbc_configuration.view());
1334 break;
1335 case android_emb::A2dpCodecType::AAC:
1336 view.aac_codec_information().CopyFrom(
1337 const_cast<l2cap::A2dpOffloadManager::Configuration&>(config)
1338 .aac_configuration.view());
1339 break;
1340 case android_emb::A2dpCodecType::LDAC:
1341 view.ldac_codec_information().CopyFrom(
1342 const_cast<l2cap::A2dpOffloadManager::Configuration&>(config)
1343 .ldac_configuration.view());
1344 break;
1345 default:
1346 break;
1347 }
1348
1349 return packet.release();
1350 }
1351
StopA2dpOffloadRequest()1352 DynamicByteBuffer StopA2dpOffloadRequest() {
1353 return DynamicByteBuffer(
1354 StaticByteBuffer(LowerBits(android_hci::kA2dpOffloadCommand),
1355 UpperBits(android_hci::kA2dpOffloadCommand),
1356 0x01, // parameter_total_size (1 byte)
1357 android_hci::kStopA2dpOffloadCommandSubopcode));
1358 }
1359
SynchronousConnectionCompletePacket(hci_spec::ConnectionHandle conn,DeviceAddress address,hci_spec::LinkType link_type,pw::bluetooth::emboss::StatusCode status)1360 DynamicByteBuffer SynchronousConnectionCompletePacket(
1361 hci_spec::ConnectionHandle conn,
1362 DeviceAddress address,
1363 hci_spec::LinkType link_type,
1364 pw::bluetooth::emboss::StatusCode status) {
1365 const auto addr = address.value().bytes();
1366 return DynamicByteBuffer(StaticByteBuffer(
1367 hci_spec::kSynchronousConnectionCompleteEventCode,
1368 0x11, // parameter_total_size (17 bytes)
1369 status, // Status
1370 LowerBits(conn), // Connection_Handle
1371 UpperBits(conn), // Connection_Handle
1372 // peer BD_ADDR (6 bytes)
1373 addr[0],
1374 addr[1],
1375 addr[2],
1376 addr[3],
1377 addr[4],
1378 addr[5],
1379 link_type, // Link_Type
1380 0x00, // Transmission_Interval interval
1381 0x00, // Retransmission_Window
1382 0x00, // RX_Packet_Length
1383 0x00, // RX_Packet_Length
1384 0x00, // TX_Packet_Length
1385 0x00, // TX_Packet_Length
1386 0x00 // Air_Mode
1387 ));
1388 }
1389
UserConfirmationRequestPacket(DeviceAddress address,uint32_t passkey)1390 DynamicByteBuffer UserConfirmationRequestPacket(DeviceAddress address,
1391 uint32_t passkey) {
1392 const auto addr = address.value().bytes();
1393 const auto passkey_bytes = ToBytes(passkey);
1394 return DynamicByteBuffer(StaticByteBuffer(
1395 hci_spec::kUserConfirmationRequestEventCode,
1396 0x0A, // parameter_total_size (10 bytes)
1397 // peer BD_ADDR (6 bytes)
1398 addr[0],
1399 addr[1],
1400 addr[2],
1401 addr[3],
1402 addr[4],
1403 addr[5],
1404 passkey_bytes[0], // Numeric_Value
1405 passkey_bytes[1], // Numeric_Value
1406 passkey_bytes[2], // Numeric_Value
1407 passkey_bytes[3] // Numeric_Value
1408 ));
1409 }
1410
UserConfirmationRequestNegativeReplyPacket(DeviceAddress address)1411 DynamicByteBuffer UserConfirmationRequestNegativeReplyPacket(
1412 DeviceAddress address) {
1413 const auto addr = address.value().bytes();
1414 return DynamicByteBuffer(StaticByteBuffer(
1415 LowerBits(hci_spec::kUserConfirmationRequestNegativeReply),
1416 UpperBits(hci_spec::kUserConfirmationRequestNegativeReply),
1417 0x06, // parameter_total_size (6 bytes)
1418 // peer BD_ADDR (6 bytes)
1419 addr[0],
1420 addr[1],
1421 addr[2],
1422 addr[3],
1423 addr[4],
1424 addr[5]));
1425 }
1426
UserConfirmationRequestReplyPacket(DeviceAddress address)1427 DynamicByteBuffer UserConfirmationRequestReplyPacket(DeviceAddress address) {
1428 const auto addr = address.value().bytes();
1429 return DynamicByteBuffer(
1430 StaticByteBuffer(LowerBits(hci_spec::kUserConfirmationRequestReply),
1431 UpperBits(hci_spec::kUserConfirmationRequestReply),
1432 0x06, // parameter_total_size (6 bytes)
1433 // peer BD_ADDR (6 bytes)
1434 addr[0],
1435 addr[1],
1436 addr[2],
1437 addr[3],
1438 addr[4],
1439 addr[5]));
1440 }
1441
UserPasskeyNotificationPacket(DeviceAddress address,uint32_t passkey)1442 DynamicByteBuffer UserPasskeyNotificationPacket(DeviceAddress address,
1443 uint32_t passkey) {
1444 const auto addr = address.value().bytes();
1445 const auto passkey_bytes = ToBytes(passkey);
1446 return DynamicByteBuffer(StaticByteBuffer(
1447 hci_spec::kUserPasskeyNotificationEventCode,
1448 0x0A, // parameter_total_size (10 bytes)
1449 // peer BD_ADDR (6 bytes)
1450 addr[0],
1451 addr[1],
1452 addr[2],
1453 addr[3],
1454 addr[4],
1455 addr[5],
1456 passkey_bytes[0], // Numeric_Value
1457 passkey_bytes[1], // Numeric_Value
1458 passkey_bytes[2], // Numeric_Value
1459 passkey_bytes[3] // Numeric_Value
1460 ));
1461 }
1462
UserPasskeyRequestNegativeReply(DeviceAddress address)1463 DynamicByteBuffer UserPasskeyRequestNegativeReply(DeviceAddress address) {
1464 const auto addr = address.value().bytes();
1465 return DynamicByteBuffer(
1466 StaticByteBuffer(LowerBits(hci_spec::kUserPasskeyRequestNegativeReply),
1467 UpperBits(hci_spec::kUserPasskeyRequestNegativeReply),
1468 0x06, // parameter_total_size (6 bytes)
1469 // peer BD_ADDR (6 bytes)
1470 addr[0],
1471 addr[1],
1472 addr[2],
1473 addr[3],
1474 addr[4],
1475 addr[5]));
1476 }
1477
UserPasskeyRequestNegativeReplyResponse(DeviceAddress address)1478 DynamicByteBuffer UserPasskeyRequestNegativeReplyResponse(
1479 DeviceAddress address) {
1480 const auto addr = address.value().bytes();
1481 return DynamicByteBuffer(StaticByteBuffer(
1482 hci_spec::kCommandCompleteEventCode,
1483 0x0A, // parameter_total_size (10 bytes)
1484 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
1485 LowerBits(hci_spec::kUserPasskeyRequestNegativeReply), // Command_Opcode
1486 UpperBits(hci_spec::kUserPasskeyRequestNegativeReply), // Command_Opcode
1487 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1488 // peer BD_ADDR (6 bytes)
1489 addr[0],
1490 addr[1],
1491 addr[2],
1492 addr[3],
1493 addr[4],
1494 addr[5]));
1495 }
1496
UserPasskeyRequestPacket(DeviceAddress address)1497 DynamicByteBuffer UserPasskeyRequestPacket(DeviceAddress address) {
1498 const auto addr = address.value().bytes();
1499 return DynamicByteBuffer(
1500 StaticByteBuffer(hci_spec::kUserPasskeyRequestEventCode,
1501 0x06, // parameter_total_size (6 bytes)
1502 // peer BD_ADDR (6 bytes)
1503 addr[0],
1504 addr[1],
1505 addr[2],
1506 addr[3],
1507 addr[4],
1508 addr[5]));
1509 }
1510
UserPasskeyRequestReplyPacket(DeviceAddress address,uint32_t passkey)1511 DynamicByteBuffer UserPasskeyRequestReplyPacket(DeviceAddress address,
1512 uint32_t passkey) {
1513 const auto addr = address.value().bytes();
1514 const auto passkey_bytes = ToBytes(passkey);
1515 return DynamicByteBuffer(StaticByteBuffer(
1516 LowerBits(hci_spec::kUserPasskeyRequestReply),
1517 UpperBits(hci_spec::kUserPasskeyRequestReply),
1518 0x0A, // parameter_total_size (10 bytes)
1519 // peer BD_ADDR (6 bytes)
1520 addr[0],
1521 addr[1],
1522 addr[2],
1523 addr[3],
1524 addr[4],
1525 addr[5],
1526 passkey_bytes[0], // Numeric_Value
1527 passkey_bytes[1], // Numeric_Value
1528 passkey_bytes[2], // Numeric_Value
1529 passkey_bytes[3] // Numeric_Value
1530 ));
1531 }
1532
UserPasskeyRequestReplyResponse(DeviceAddress address)1533 DynamicByteBuffer UserPasskeyRequestReplyResponse(DeviceAddress address) {
1534 const auto addr = address.value().bytes();
1535 return DynamicByteBuffer(StaticByteBuffer(
1536 hci_spec::kCommandCompleteEventCode,
1537 0x0A, // parameter_total_size (10 bytes)
1538 0xF0, // Num_HCI_Command_Packets allowed to be sent to controller (240)
1539 LowerBits(hci_spec::kUserPasskeyRequestReply), // Command_Opcode
1540 UpperBits(hci_spec::kUserPasskeyRequestReply), // Command_Opcode
1541 pw::bluetooth::emboss::StatusCode::SUCCESS, // Status
1542 // peer BD_ADDR (6 bytes)
1543 addr[0],
1544 addr[1],
1545 addr[2],
1546 addr[3],
1547 addr[4],
1548 addr[5]));
1549 }
1550
WriteAutomaticFlushTimeoutPacket(hci_spec::ConnectionHandle conn,uint16_t flush_timeout)1551 DynamicByteBuffer WriteAutomaticFlushTimeoutPacket(
1552 hci_spec::ConnectionHandle conn, uint16_t flush_timeout) {
1553 return DynamicByteBuffer(StaticByteBuffer(
1554 LowerBits(hci_spec::kWriteAutomaticFlushTimeout),
1555 UpperBits(hci_spec::kWriteAutomaticFlushTimeout),
1556 0x04, // parameter_total_size (4 bytes)
1557 LowerBits(conn), // Connection_Handle
1558 UpperBits(conn), // Connection_Handle
1559 LowerBits(flush_timeout), // Flush_Timeout
1560 UpperBits(flush_timeout) // Flush_Timeout
1561 ));
1562 }
1563
WriteInquiryScanActivity(uint16_t scan_interval,uint16_t scan_window)1564 DynamicByteBuffer WriteInquiryScanActivity(uint16_t scan_interval,
1565 uint16_t scan_window) {
1566 return DynamicByteBuffer(StaticByteBuffer(
1567 LowerBits(hci_spec::kWriteInquiryScanActivity),
1568 UpperBits(hci_spec::kWriteInquiryScanActivity),
1569 0x04, // parameter_total_size (4 bytes)
1570 LowerBits(scan_interval), // Inquiry_Scan_Interval
1571 UpperBits(scan_interval), // Inquiry_Scan_Interval
1572 LowerBits(scan_window), // Inquiry_Scan_Window
1573 UpperBits(scan_window) // Inquiry_Scan_Window
1574 ));
1575 }
1576
WritePageScanActivityPacket(uint16_t scan_interval,uint16_t scan_window)1577 DynamicByteBuffer WritePageScanActivityPacket(uint16_t scan_interval,
1578 uint16_t scan_window) {
1579 return DynamicByteBuffer(StaticByteBuffer(
1580 LowerBits(hci_spec::kWritePageScanActivity),
1581 UpperBits(hci_spec::kWritePageScanActivity),
1582 0x04, // parameter_total_size (4 bytes)
1583 LowerBits(scan_interval), // Page_Scan_Interval
1584 UpperBits(scan_interval), // Page_Scan_Interval
1585 LowerBits(scan_window), // Page_Scan_Window
1586 UpperBits(scan_window) // Page_Scan_Window
1587 ));
1588 }
1589
WritePageScanTypePacket(uint8_t scan_type)1590 DynamicByteBuffer WritePageScanTypePacket(uint8_t scan_type) {
1591 return DynamicByteBuffer(StaticByteBuffer(
1592 LowerBits(hci_spec::kWritePageScanType),
1593 UpperBits(hci_spec::kWritePageScanType),
1594 0x01, // parameter_total_size (1 byte)
1595 scan_type // Page_Scan_Type
1596 ));
1597 }
1598
WritePageScanTypeResponse()1599 DynamicByteBuffer WritePageScanTypeResponse() {
1600 return CommandCompletePacket(hci_spec::kWritePageScanType,
1601 pw::bluetooth::emboss::StatusCode::SUCCESS);
1602 }
1603
WritePageTimeoutPacket(uint16_t page_timeout)1604 DynamicByteBuffer WritePageTimeoutPacket(uint16_t page_timeout) {
1605 return DynamicByteBuffer(StaticByteBuffer(
1606 LowerBits(hci_spec::kWritePageTimeout),
1607 UpperBits(hci_spec::kWritePageTimeout),
1608 0x02, // parameter_total_size (2 bytes)
1609 LowerBits(page_timeout), // Page_Timeout
1610 UpperBits(page_timeout) // Page_Timeout
1611 ));
1612 }
1613
WritePinTypePacket(uint8_t pin_type)1614 DynamicByteBuffer WritePinTypePacket(uint8_t pin_type) {
1615 return DynamicByteBuffer(StaticByteBuffer(
1616 LowerBits(hci_spec::kWritePinType),
1617 UpperBits(hci_spec::kWritePinType),
1618 0x01, // parameter_total_size (1 byte)
1619 pin_type // PIN_Type
1620 ));
1621 }
1622
WriteScanEnable(uint8_t scan_enable)1623 DynamicByteBuffer WriteScanEnable(uint8_t scan_enable) {
1624 return DynamicByteBuffer(StaticByteBuffer(
1625 LowerBits(hci_spec::kWriteScanEnable),
1626 UpperBits(hci_spec::kWriteScanEnable),
1627 0x01, // parameter_total_size (1 byte)
1628 scan_enable // Scan_Enable
1629 ));
1630 }
1631
1632 } // namespace bt::testing
1633