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 "h4_protocol.h"
18761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
19761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#define LOG_TAG "android.hardware.bluetooth-hci-h4"
20761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <android-base/logging.h>
21761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <assert.h>
22761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <fcntl.h>
23761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
24761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace android {
25761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hardware {
26761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace bluetooth {
27761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hci {
28761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
29761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonsize_t H4Protocol::Send(uint8_t type, const uint8_t* data, size_t length) {
30761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  int rv = WriteSafely(uart_fd_, &type, sizeof(type));
31761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  if (rv == sizeof(type)) {
32761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    rv = WriteSafely(uart_fd_, data, length);
33761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  }
34761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  return rv;
35761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
36761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
37761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonvoid H4Protocol::OnPacketReady() {
38761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  switch (hci_packet_type_) {
39761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    case HCI_PACKET_TYPE_EVENT:
40761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      event_cb_(hci_packetizer_.GetPacket());
41761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
42761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    case HCI_PACKET_TYPE_ACL_DATA:
43761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      acl_cb_(hci_packetizer_.GetPacket());
44761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
45761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    case HCI_PACKET_TYPE_SCO_DATA:
46761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      sco_cb_(hci_packetizer_.GetPacket());
47761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
48761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    default: {
49761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      bool bad_packet_type = true;
50761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      CHECK(!bad_packet_type);
51761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    }
52761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  }
53761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  // Get ready for the next type byte.
54761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  hci_packet_type_ = HCI_PACKET_TYPE_UNKNOWN;
55761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
56761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
57761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonvoid H4Protocol::OnDataReady(int fd) {
58761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  if (hci_packet_type_ == HCI_PACKET_TYPE_UNKNOWN) {
59761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    uint8_t buffer[1] = {0};
60761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
61761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    CHECK(bytes_read == 1);
62761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    hci_packet_type_ = static_cast<HciPacketType>(buffer[0]);
63761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  } else {
64761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    hci_packetizer_.OnDataReady(fd, hci_packet_type_);
65761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  }
66761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
67761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
68761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace hci
69761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace bluetooth
70761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace hardware
71761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace android
72