1761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// 2761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Copyright 2017 The Android Open Source Project 3761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// 4761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Licensed under the Apache License, Version 2.0 (the "License"); 5761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// you may not use this file except in compliance with the License. 6761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// You may obtain a copy of the License at 7761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// 8761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// http://www.apache.org/licenses/LICENSE-2.0 9761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// 10761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Unless required by applicable law or agreed to in writing, software 11761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// distributed under the License is distributed on an "AS IS" BASIS, 12761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// See the License for the specific language governing permissions and 14761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// limitations under the License. 15761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// 16761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 17761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include "hci_packetizer.h" 18761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 19761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#define LOG_TAG "android.hardware.bluetooth.hci_packetizer" 20761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <android-base/logging.h> 21761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <utils/Log.h> 22761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 23761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <dlfcn.h> 24761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <fcntl.h> 25761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 26761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace { 27761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 28761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst size_t preamble_size_for_type[] = { 29761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE, 30761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson HCI_EVENT_PREAMBLE_SIZE}; 31761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst size_t packet_length_offset_for_type[] = { 32761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO, 33761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson HCI_LENGTH_OFFSET_EVT}; 34761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 35761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonsize_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) { 36761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson size_t offset = packet_length_offset_for_type[type]; 37761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset]; 38761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson return (((preamble[offset + 1]) << 8) | preamble[offset]); 39761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} 40761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 41761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} // namespace 42761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 43761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace android { 44761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hardware { 45761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace bluetooth { 46761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hci { 47761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 48761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; } 49761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 50761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonvoid HciPacketizer::OnDataReady(int fd, HciPacketType packet_type) { 51761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson switch (state_) { 52761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson case HCI_PREAMBLE: { 53761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson size_t bytes_read = TEMP_FAILURE_RETRY( 54761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson read(fd, preamble_ + bytes_read_, 55761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson preamble_size_for_type[packet_type] - bytes_read_)); 56761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson CHECK(bytes_read > 0); 57761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_read_ += bytes_read; 58761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson if (bytes_read_ == preamble_size_for_type[packet_type]) { 59761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson size_t packet_length = 60761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson HciGetPacketLengthForType(packet_type, preamble_); 61761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson packet_.resize(preamble_size_for_type[packet_type] + packet_length); 62761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson memcpy(packet_.data(), preamble_, preamble_size_for_type[packet_type]); 63761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_remaining_ = packet_length; 64761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson state_ = HCI_PAYLOAD; 65761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_read_ = 0; 66761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson } 67761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson break; 68761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson } 69761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 70761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson case HCI_PAYLOAD: { 71761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson size_t bytes_read = TEMP_FAILURE_RETRY(read( 72761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson fd, 73761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson packet_.data() + preamble_size_for_type[packet_type] + bytes_read_, 74761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_remaining_)); 75761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson CHECK(bytes_read > 0); 76761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_remaining_ -= bytes_read; 77761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_read_ += bytes_read; 78761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson if (bytes_remaining_ == 0) { 79761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson packet_ready_cb_(); 80761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson state_ = HCI_PREAMBLE; 81761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson bytes_read_ = 0; 82761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson } 83761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson break; 84761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson } 85761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson } 86761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} 87761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson 88761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} // namespace hci 89761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} // namespace bluetooth 90761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} // namespace hardware 91761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson} // namespace android 92