• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/transport/sco_data_packet.h"
16 
17 #include <endian.h>
18 
19 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
20 #include "pw_bluetooth_sapphire/internal/host/transport/slab_allocators.h"
21 
22 namespace bt::hci {
23 // Type containing both a fixed packet storage buffer and a ScoDataPacket
24 // interface to the buffer.
25 using MaxScoDataPacket =
26     allocators::internal::FixedSizePacket<hci_spec::SynchronousDataHeader,
27                                           allocators::kMaxScoDataPacketSize>;
28 
New(uint8_t payload_size)29 std::unique_ptr<ScoDataPacket> ScoDataPacket::New(uint8_t payload_size) {
30   return std::make_unique<MaxScoDataPacket>(payload_size);
31 }
32 
New(hci_spec::ConnectionHandle connection_handle,uint8_t payload_size)33 std::unique_ptr<ScoDataPacket> ScoDataPacket::New(
34     hci_spec::ConnectionHandle connection_handle, uint8_t payload_size) {
35   std::unique_ptr<ScoDataPacket> packet = ScoDataPacket::New(payload_size);
36   packet->WriteHeader(connection_handle);
37   return packet;
38 }
39 
connection_handle() const40 hci_spec::ConnectionHandle ScoDataPacket::connection_handle() const {
41   // Return the lower 12-bits of the first two octets.
42   return le16toh(view().header().handle_and_flags) & 0x0FFF;
43 }
packet_status_flag() const44 hci_spec::SynchronousDataPacketStatusFlag ScoDataPacket::packet_status_flag()
45     const {
46   // Return bits 4-5 in the higher octet of |handle_and_flags|, i.e.
47   // 0b00xx000000000000.
48   return static_cast<hci_spec::SynchronousDataPacketStatusFlag>(
49       (le16toh(view().header().handle_and_flags) >> 12) & 0x0003);
50 }
51 
InitializeFromBuffer()52 void ScoDataPacket::InitializeFromBuffer() {
53   mutable_view()->Resize(
54       /*payload_size=*/le16toh(view().header().data_total_length));
55 }
56 
WriteHeader(hci_spec::ConnectionHandle connection_handle)57 void ScoDataPacket::WriteHeader(hci_spec::ConnectionHandle connection_handle) {
58   // Handle must fit inside 12-bits.
59   BT_ASSERT(connection_handle <= 0x0FFF);
60   // This sets the Packet Status Flag (upper bits of handle_and_flags) to 0,
61   // which is required for Host->Controller SCO packets.
62   mutable_view()->mutable_header()->handle_and_flags =
63       htole16(connection_handle);
64   mutable_view()->mutable_header()->data_total_length =
65       static_cast<uint8_t>(view().payload_size());
66 }
67 
68 }  // namespace bt::hci
69