xref: /aosp_15_r20/hardware/interfaces/bluetooth/1.0/default/hci_packetizer.cc (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker //
2*4d7e907cSAndroid Build Coastguard Worker // Copyright 2017 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker //
4*4d7e907cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker //
8*4d7e907cSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker //
10*4d7e907cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker // limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker //
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #include "hci_packetizer.h"
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "android.hardware.bluetooth.hci_packetizer"
20*4d7e907cSAndroid Build Coastguard Worker 
21*4d7e907cSAndroid Build Coastguard Worker #include <dlfcn.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <errno.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <fcntl.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <unistd.h>
25*4d7e907cSAndroid Build Coastguard Worker #include <utils/Log.h>
26*4d7e907cSAndroid Build Coastguard Worker 
27*4d7e907cSAndroid Build Coastguard Worker namespace {
28*4d7e907cSAndroid Build Coastguard Worker 
29*4d7e907cSAndroid Build Coastguard Worker const size_t preamble_size_for_type[] = {0,
30*4d7e907cSAndroid Build Coastguard Worker                                          HCI_COMMAND_PREAMBLE_SIZE,
31*4d7e907cSAndroid Build Coastguard Worker                                          HCI_ACL_PREAMBLE_SIZE,
32*4d7e907cSAndroid Build Coastguard Worker                                          HCI_SCO_PREAMBLE_SIZE,
33*4d7e907cSAndroid Build Coastguard Worker                                          HCI_EVENT_PREAMBLE_SIZE,
34*4d7e907cSAndroid Build Coastguard Worker                                          HCI_ISO_PREAMBLE_SIZE};
35*4d7e907cSAndroid Build Coastguard Worker const size_t packet_length_offset_for_type[] = {0,
36*4d7e907cSAndroid Build Coastguard Worker                                                 HCI_LENGTH_OFFSET_CMD,
37*4d7e907cSAndroid Build Coastguard Worker                                                 HCI_LENGTH_OFFSET_ACL,
38*4d7e907cSAndroid Build Coastguard Worker                                                 HCI_LENGTH_OFFSET_SCO,
39*4d7e907cSAndroid Build Coastguard Worker                                                 HCI_LENGTH_OFFSET_EVT,
40*4d7e907cSAndroid Build Coastguard Worker                                                 HCI_LENGTH_OFFSET_ISO};
41*4d7e907cSAndroid Build Coastguard Worker 
HciGetPacketLengthForType(HciPacketType type,const uint8_t * preamble)42*4d7e907cSAndroid Build Coastguard Worker size_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) {
43*4d7e907cSAndroid Build Coastguard Worker   size_t offset = packet_length_offset_for_type[type];
44*4d7e907cSAndroid Build Coastguard Worker   if (type == HCI_PACKET_TYPE_ACL_DATA) {
45*4d7e907cSAndroid Build Coastguard Worker     return (((preamble[offset + 1]) << 8) | preamble[offset]);
46*4d7e907cSAndroid Build Coastguard Worker   } else if (type == HCI_PACKET_TYPE_ISO_DATA) {
47*4d7e907cSAndroid Build Coastguard Worker     return ((((preamble[offset + 1]) & 0x3f) << 8) | preamble[offset]);
48*4d7e907cSAndroid Build Coastguard Worker   }
49*4d7e907cSAndroid Build Coastguard Worker   return preamble[offset];
50*4d7e907cSAndroid Build Coastguard Worker }
51*4d7e907cSAndroid Build Coastguard Worker 
52*4d7e907cSAndroid Build Coastguard Worker }  // namespace
53*4d7e907cSAndroid Build Coastguard Worker 
54*4d7e907cSAndroid Build Coastguard Worker namespace android {
55*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
56*4d7e907cSAndroid Build Coastguard Worker namespace bluetooth {
57*4d7e907cSAndroid Build Coastguard Worker namespace hci {
58*4d7e907cSAndroid Build Coastguard Worker 
GetPacket() const59*4d7e907cSAndroid Build Coastguard Worker const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
60*4d7e907cSAndroid Build Coastguard Worker 
OnDataReady(int fd,HciPacketType packet_type)61*4d7e907cSAndroid Build Coastguard Worker void HciPacketizer::OnDataReady(int fd, HciPacketType packet_type) {
62*4d7e907cSAndroid Build Coastguard Worker   switch (state_) {
63*4d7e907cSAndroid Build Coastguard Worker     case HCI_PREAMBLE: {
64*4d7e907cSAndroid Build Coastguard Worker       ssize_t bytes_read = TEMP_FAILURE_RETRY(
65*4d7e907cSAndroid Build Coastguard Worker           read(fd, preamble_ + bytes_read_,
66*4d7e907cSAndroid Build Coastguard Worker                preamble_size_for_type[packet_type] - bytes_read_));
67*4d7e907cSAndroid Build Coastguard Worker       if (bytes_read == 0) {
68*4d7e907cSAndroid Build Coastguard Worker         // This is only expected if the UART got closed when shutting down.
69*4d7e907cSAndroid Build Coastguard Worker         ALOGE("%s: Unexpected EOF reading the header!", __func__);
70*4d7e907cSAndroid Build Coastguard Worker         sleep(5);  // Expect to be shut down within 5 seconds.
71*4d7e907cSAndroid Build Coastguard Worker         return;
72*4d7e907cSAndroid Build Coastguard Worker       }
73*4d7e907cSAndroid Build Coastguard Worker       if (bytes_read < 0) {
74*4d7e907cSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("%s: Read header error: %s", __func__,
75*4d7e907cSAndroid Build Coastguard Worker                          strerror(errno));
76*4d7e907cSAndroid Build Coastguard Worker       }
77*4d7e907cSAndroid Build Coastguard Worker       bytes_read_ += bytes_read;
78*4d7e907cSAndroid Build Coastguard Worker       if (bytes_read_ == preamble_size_for_type[packet_type]) {
79*4d7e907cSAndroid Build Coastguard Worker         size_t packet_length =
80*4d7e907cSAndroid Build Coastguard Worker             HciGetPacketLengthForType(packet_type, preamble_);
81*4d7e907cSAndroid Build Coastguard Worker         packet_.resize(preamble_size_for_type[packet_type] + packet_length);
82*4d7e907cSAndroid Build Coastguard Worker         memcpy(packet_.data(), preamble_, preamble_size_for_type[packet_type]);
83*4d7e907cSAndroid Build Coastguard Worker         bytes_remaining_ = packet_length;
84*4d7e907cSAndroid Build Coastguard Worker         state_ = HCI_PAYLOAD;
85*4d7e907cSAndroid Build Coastguard Worker         bytes_read_ = 0;
86*4d7e907cSAndroid Build Coastguard Worker       }
87*4d7e907cSAndroid Build Coastguard Worker       break;
88*4d7e907cSAndroid Build Coastguard Worker     }
89*4d7e907cSAndroid Build Coastguard Worker 
90*4d7e907cSAndroid Build Coastguard Worker     case HCI_PAYLOAD: {
91*4d7e907cSAndroid Build Coastguard Worker       ssize_t bytes_read = TEMP_FAILURE_RETRY(read(
92*4d7e907cSAndroid Build Coastguard Worker           fd,
93*4d7e907cSAndroid Build Coastguard Worker           packet_.data() + preamble_size_for_type[packet_type] + bytes_read_,
94*4d7e907cSAndroid Build Coastguard Worker           bytes_remaining_));
95*4d7e907cSAndroid Build Coastguard Worker       if (bytes_read == 0) {
96*4d7e907cSAndroid Build Coastguard Worker         // This is only expected if the UART got closed when shutting down.
97*4d7e907cSAndroid Build Coastguard Worker         ALOGE("%s: Unexpected EOF reading the payload!", __func__);
98*4d7e907cSAndroid Build Coastguard Worker         sleep(5);  // Expect to be shut down within 5 seconds.
99*4d7e907cSAndroid Build Coastguard Worker         return;
100*4d7e907cSAndroid Build Coastguard Worker       }
101*4d7e907cSAndroid Build Coastguard Worker       if (bytes_read < 0) {
102*4d7e907cSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("%s: Read payload error: %s", __func__,
103*4d7e907cSAndroid Build Coastguard Worker                          strerror(errno));
104*4d7e907cSAndroid Build Coastguard Worker       }
105*4d7e907cSAndroid Build Coastguard Worker       bytes_remaining_ -= bytes_read;
106*4d7e907cSAndroid Build Coastguard Worker       bytes_read_ += bytes_read;
107*4d7e907cSAndroid Build Coastguard Worker       if (bytes_remaining_ == 0) {
108*4d7e907cSAndroid Build Coastguard Worker         packet_ready_cb_();
109*4d7e907cSAndroid Build Coastguard Worker         state_ = HCI_PREAMBLE;
110*4d7e907cSAndroid Build Coastguard Worker         bytes_read_ = 0;
111*4d7e907cSAndroid Build Coastguard Worker       }
112*4d7e907cSAndroid Build Coastguard Worker       break;
113*4d7e907cSAndroid Build Coastguard Worker     }
114*4d7e907cSAndroid Build Coastguard Worker   }
115*4d7e907cSAndroid Build Coastguard Worker }
116*4d7e907cSAndroid Build Coastguard Worker 
117*4d7e907cSAndroid Build Coastguard Worker }  // namespace hci
118*4d7e907cSAndroid Build Coastguard Worker }  // namespace bluetooth
119*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
120*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
121